How to convert csv to json for postman collection runs
- Step 1Build your test-data CSV — One row per iteration, header row as variable names. A header
agebecomes the{{age}}variable in your requests and theagekey your test scripts read. Use the exact variable names your collection references. - Step 2Drop the CSV onto the converter above — Accepts
.csv,.tsv,.txt. PapaParse auto-detects the delimiter and keeps commas inside quoted cells, so a test value like"a, b"stays one field. - Step 3Choose Array of objects — Postman's Runner and Newman iterate over a JSON array, one object per iteration. Keep the default Array of objects mode. The preview shows the first records so you can confirm variable names match your collection.
- Step 4Leave type inference on for typed assertions — Keep Infer numbers, booleans, null on so
{{age}}is a number and{{active}}a boolean. Yourpm.expect(...).to.eql(36)andto.be.trueassertions then compare against real types, not strings. - Step 5Pick an indent (cosmetic) — Indent is purely for readability of the data file — the Runner parses any valid JSON the same way. 2 spaces is fine; Minified if you keep the file small in version control.
- Step 6Download and attach as the data file — Download JSON, then in the Collection Runner choose this file under Data, or with Newman run
newman run collection.json -d data.json. Each array element drives one iteration.
CSV data file vs JSON data file in Postman
Why a JSON iteration file beats a raw CSV for data-driven tests.
| Aspect | CSV data file | JSON data file (from this tool) |
|---|---|---|
{{age}} type | always string "36" | number 36 (inference on) |
{{active}} in if | truthy string even when "false" | real boolean false |
pm.expect().to.eql(36) | fails (string vs number) | passes |
| null value | empty string | JSON null (literal null cell) |
| Comma inside a value | needs careful quoting | preserved by quote-aware parser |
Inference and what your test script sees
Inference is a single global toggle. Off means every iteration value is a string.
| CSV cell | JSON value (inference on) | In pm script / {{var}} |
|---|---|---|
36 | 36 | number |
true | true | boolean (use .to.be.true) |
null | null | null (use .to.be.null) |
007 | 7 | number — leading zero lost |
+15550100 | "+15550100" | string (does not match number pattern) |
| `` (empty) | "" | empty string (or key omitted with Skip empty cells) |
Cookbook
Conversion recipes for Postman Collection Runner and Newman data-driven runs.
Typed iteration data for the Collection Runner
ExampleDefault settings. Each object is one iteration; age is a number and active a boolean, so typed assertions pass.
Input (testdata.csv):
email,age,active
a@x.com,36,true
b@x.com,54,false
Output (array, inference on):
[
{ "email": "a@x.com", "age": 36, "active": true },
{ "email": "b@x.com", "age": 54, "active": false }
]
// In a test: pm.expect(pm.response.json().age).to.eql(Number(pm.iterationData.get('age')))Run it with Newman
ExampleUse the downloaded array as Newman's data file. One iteration per array element.
Output saved as data.json (array of N objects)
newman run collection.json -d data.json
→ runs N iterations, {{email}} {{age}} {{active}} bound per rowNull iteration value for negative tests
ExampleA literal null cell becomes JSON null, so you can drive a negative test that sends a null field and asserts the API's validation error.
Input:
name,phone
Ada,null
Output:
[ { "name": "Ada", "phone": null } ]
// pm.test('rejects null phone', () => pm.expect(pm.response.code).to.eql(422))Build a typed request body from a row
ExampleUse the converted object as the JSON body of a POST under test. Numbers and flags are already typed, so the API sees a realistic payload.
Output element used as body:
{ "sku": "A-1", "qty": 3, "giftWrap": true }
// Request body (raw JSON), referencing iteration vars:
{ "sku": "{{sku}}", "qty": {{qty}}, "giftWrap": {{giftWrap}} }Keep an order number as a string
ExampleOrder IDs with leading zeros must stay verbatim. Turn inference off so {{orderId}} is the exact string.
Input:
orderId,total
00087,19.99
Output (inference OFF):
[ { "orderId": "00087", "total": "19.99" } ]
→ {{orderId}} resolves to "00087"Errors and edge cases
Real errors and silent failures sourced from each platform's own documentation. Match the wording to the row, fix what the row says to fix.
Boolean iteration value behaves as a string in CSV mode
Fixed by JSONWith a CSV data file, {{active}} is the string "false", which is truthy in JavaScript — so if (pm.iterationData.get('active')) runs the true branch even when the value is false. Converting to JSON with inference on makes it a real boolean, so the condition behaves correctly. This is the single biggest reason to use a JSON data file.
Order/ID iteration value loses leading zeros
By designInference turns 00087 into 87. If {{orderId}} must keep its zeros for the request, turn off Infer numbers, booleans, null so it stays a string. Inference is global, so the trade-off is that genuinely numeric vars also become strings — wrap them in Number(...) in your scripts if needed.
Null vs empty string in a negative test
ExpectedA blank cell becomes ""; only the literal word null becomes JSON null. For a negative test that must send a true null, put null in the CSV cell. To send no field at all (testing 'missing required field'), turn on Skip empty cells so blank cells omit the key entirely.
Duplicate variable name in the header
OverwriteTwo columns named id collapse to one JSON key (later wins), so one of the iteration values is lost. Rename one column before converting so both variables exist in each iteration object.
{{var}} resolves but the type is wrong in the body
Templating gotchaIn a raw JSON request body, "qty": "{{qty}}" always sends a string because of the quotes. To send a number, write "qty": {{qty}} (no quotes) and ensure the data file has a real number — which inference provides. The converter gives you the typed value; the body template controls how it is injected.
Empty cell omitted unexpectedly
ExpectedWith Skip empty cells on, a blank cell drops the key — so pm.iterationData.get('x') returns undefined for that iteration. If your tests expect the key to always exist (as an empty string), leave Skip empty cells off.
Free tier cap on a large data set
LimitFree tier caps at 2 MB / 500 rows — usually plenty for a data-driven test, since Runner iterations rarely number in the thousands. For a large soak/load fixture, Pro raises it to 100 MB / 100,000 rows. Newman has no inherent iteration limit; the constraint is the converter tier here.
Header has spaces and your script uses bracket access
WorkableA header User Name becomes the key User Name (spaces preserved). {{User Name}} still works in requests, and in scripts use pm.iterationData.get('User Name'). If you prefer dot access, rename the column to userName in the source CSV before converting.
Frequently asked questions
Why use a JSON data file instead of CSV in the Collection Runner?
Because a JSON data file preserves value types. With a CSV, every {{var}} is a string — {{age}} is "36" and {{active}} is "true" (truthy even when false). A JSON array keeps 36 a number and false a real boolean, so your assertions and conditional logic behave correctly. This converter produces that typed array from your CSV.
Does this work with Newman as well as the GUI Runner?
Yes. Newman accepts the same JSON data file: newman run collection.json -d data.json. Each element of the array drives one iteration, exactly as in the Collection Runner. Use Array output mode for both.
How do I assert against a number from the iteration data?
With inference on, the iteration value is already a number, so pm.expect(pm.response.json().age).to.eql(pm.iterationData.get('age')) compares number to number. If you kept inference off, wrap it: Number(pm.iterationData.get('age')).
How do I send a number (not a string) in a JSON request body?
In the raw body, omit the quotes around the variable: "qty": {{qty}} not "qty": "{{qty}}". Ensure the data file has a real number for qty, which inference provides. Quotes around {{var}} always produce a string in the body.
Can I drive a negative test with a null value?
Yes. Put the literal word null in the CSV cell; with inference on it becomes JSON null in the iteration object, so the request sends a real null. To test a missing field instead, turn on Skip empty cells and leave the cell blank so the key is omitted.
Will my test fixtures be uploaded?
No. Conversion runs in your browser via PapaParse. Fixture contents — including any real values you test with — never reach a JAD Apps server. Only an anonymous run counter is stored when signed in, and you can opt out.
My order IDs lose their leading zeros — how do I keep them?
Turn off type inference so every value stays a string, including IDs like 00087. The trade-off is that numeric variables also become strings; cast them in your scripts with Number(...) where you need arithmetic or numeric assertions.
How many iterations / rows can I convert?
Free tier handles up to 2 MB and 500 rows, which covers most data-driven test sets. For a large fixture, Pro raises this to 100 MB / 100,000 rows. Newman itself does not cap iterations — the limit is the conversion tier here.
Can I keep headers with spaces?
Yes — User Name stays the key User Name. Use {{User Name}} in requests and pm.iterationData.get('User Name') in scripts. If you want dot access in scripts, rename columns to identifier-style names in the CSV first.
Can I validate the generated data file before running?
Yes — run the output through json-validator to confirm it is well-formed JSON before attaching it. Or use json-tree-viewer to eyeball the structure and confirm variable names match your collection.
What output mode if a later step wants line-delimited records?
Use NDJSON. The Collection Runner wants an array, but if you chain the data into a load-test tool or a log pipeline after the Postman run, NDJSON (one object per line) is often the expected handoff format.
Can I automate generating the data file in CI?
Yes. Pair the @jadapps/runner once and POST the CSV to 127.0.0.1:9789/v1/tools/csv-to-json/run. A typical CI step: export test rows to CSV → runner converts to a typed JSON array → newman run -d data.json. The fixtures stay on the build machine and never reach JAD's servers.
Privacy first
Conversion runs locally in your browser. No file is uploaded — only metadata counters are saved for signed-in dashboard stats.