How to generate json schema for postman tv4 jsonschema assertions
- Step 1Capture a representative response in Postman — Send the request, then copy the response body. Use a
200 OKwith all optional fields populated — the schema only describes keys present in the captured sample, and for arrays the FIRST element should carry every field. - Step 2Load the response JSON — Drop the saved
.jsonbody (free tier up to 2 MB) or paste it. The tool runs strictJSON.parseon one value, so paste the response object itself — not a.jsonllog of many responses. If a captured body won't load, check it with the JSON validator first. - Step 3Name the schema — Set Schema title to the endpoint model, e.g.
GetUser200. It is written to the roottitleonly; it does not affect the assertion but documents which response the schema describes. - Step 4Choose required and additionalProperties — Keep Mark all fields required on so missing fields fail the test. Allow additional properties off writes
additionalProperties: false— note Postman's tv4 ignores it, so it only bites if you validate with AJV instead. - Step 5Generate and copy the schema — Click Generate Schema, then Copy. Create a collection variable (e.g.
GET_USER_SCHEMA) and paste the schema JSON as its value so every test on that endpoint can reuse it. - Step 6Add the test assertion — In the Tests tab:
const schema = JSON.parse(pm.collectionVariables.get('GET_USER_SCHEMA')); pm.test('matches schema', () => pm.response.to.have.jsonSchema(schema));. Convert any"type":"null"field to a nullable union first.
Where the schema runs in Postman and what enforces it
Postman's jsonSchema matcher uses Tiny Validator (tv4). Newman uses the same engine. Behavior is identical across these surfaces.
| Surface | API | Validator | Notes |
|---|---|---|---|
| Tests tab (app) | pm.response.to.have.jsonSchema(schema) | tv4 (built in) | Pasted-in schema as a collection variable is the common pattern |
| Collection Runner | same test scripts | tv4 | Runs the same assertions across the whole collection |
| Newman (CI) | same test scripts | tv4 | Include the schema variable in the collection export so CI has it |
| Strict validation | new Ajv().compile(schema) | AJV (you add it) | Use AJV when you need additionalProperties:false enforced |
What tv4 enforces vs ignores in the generated schema
Knowing this prevents 'why did my extra-key test pass?' confusion. Switch to AJV inside the test for strict checks.
| Schema feature (generated) | tv4 (Postman default) | AJV (if you add it) |
|---|---|---|
type (string/integer/number/boolean/null) | Enforced | Enforced |
required (all top-level keys) | Enforced | Enforced |
nested properties | Enforced | Enforced |
additionalProperties: false | Ignored — extra keys pass | Enforced — extra keys fail |
"type":"null" from a null sample | Fails on a real value | Fails on a real value |
Cookbook
Captured responses, the schema they produce, and the exact Postman test snippet — plus the fix for the two cases where a 'green' test is lying to you.
GET /user response to a collection-variable schema
ExampleA user response generates a strict schema you paste into a collection variable and assert in the Tests tab.
Captured 200 body:
{ "id": 7, "name": "Sue", "active": true }
Schema title: GetUser200 · required: ON
Generated:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "GetUser200",
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" },
"active": { "type": "boolean" }
},
"required": ["id", "name", "active"],
"additionalProperties": false
}The Tests tab assertion
ExampleStore the schema in a collection variable, then assert it. This runs the same in the app, the Runner, and Newman.
// Pre-req: collection variable GET_USER_SCHEMA holds the schema JSON
const schema = JSON.parse(pm.collectionVariables.get('GET_USER_SCHEMA'));
pm.test('GET /user matches schema', function () {
pm.response.to.have.jsonSchema(schema);
});Why an extra key did not fail the test
Exampletv4 ignores additionalProperties:false. To catch an unexpected debugToken field, validate with AJV inside the test instead.
Response gained an extra key: { id, name, active, debugToken }
pm.response.to.have.jsonSchema(schema) => still PASSES (tv4 ignores additionalProperties)
Strict alternative inside the Tests tab:
const Ajv = require('ajv'); // available in Postman sandbox
const validate = new Ajv().compile(schema);
pm.test('no extra keys', () => pm.expect(validate(pm.response.json())).to.be.true);
// => FAILS on debugTokenFix a nullable field before asserting
ExampleA null sample makes tv4 fail when the API returns a real value. Convert to a nullable union in the schema variable.
Captured: { "name": "Sue", "deletedAt": null }
Generated: "deletedAt": { "type": "null" }
Real later response: { name:'Sue', deletedAt:'2026-01-02T...' }
=> jsonSchema assertion FAILS (type must be null)
Edit the schema variable:
"deletedAt": { "type": ["string", "null"] }
=> both null and a timestamp pass.Schema for an array response
ExampleWhen the endpoint returns a top-level array, the schema root is an array; put a complete object first so item keys survive the merge.
Captured: [ { "id": 1, "name": "Sue" }, { "id": 2, "name": "Jon" } ]
Generated:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ListUsers200",
"type": "array",
"items": {
"type": "object",
"properties": { "id": {"type":"integer"}, "name": {"type":"string"} }
}
}
// No required/additionalProperties on an array root.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.
tv4 ignores additionalProperties:false
tv4 limitationPostman's jsonSchema matcher uses Tiny Validator (tv4), which does not enforce additionalProperties. An unexpected key in the response still passes the assertion even though the generated schema sets additionalProperties: false. To fail on extra keys, compile the schema with AJV inside the Tests tab and assert on validate(...).
A null sample value fails the test on real data
Assertion faildeletedAt: null infers "type":"null". When the endpoint later returns a real timestamp, pm.response.to.have.jsonSchema fails because the value is not null. Change the property to "type": ["string", "null"] in the collection-variable schema. Scan every null in the captured sample.
Array of objects keeps only the first element's keys
Partial schemaItem schemas merge by top-level type, so an array of objects keeps the FIRST element's shape; keys only on later items are missing from items.properties. Your assertion then won't check those fields. Capture a response whose first array element has every field, or hand-edit items.properties.
format and enum are not inferred, so tv4 won't check them
Not inferredA date string is "type":"string", not format:"date-time", and a status string is not an enum. The assertion only checks structure and types. Add format/enum/pattern by hand to the schema variable if you need the test to enforce value rules — and remember tv4's format support is partial.
Mock servers do not use JSON Schema
By designA Postman mock server returns saved Examples verbatim — it does not validate against a JSON Schema. Use this generated schema in test scripts to confirm a real response still matches the mock's shape. Save the captured body as the request's Example for the mock; use the schema for the assertion.
NDJSON or multi-response log fails to parse
Parse errorPasting several captured responses (one per line) throws Unexpected non-whitespace character after JSON — the tool parses one JSON value. Generate from a single response object, or wrap multiple in a [ ... ] array first. Reformat a messy body with the JSON prettifier before generating.
Schema variable not exported with the collection
Newman missIf the schema lives in a collection variable, make sure it is included when you export the collection for Newman. A missing variable makes JSON.parse(pm.collectionVariables.get(...)) return undefined and the assertion throw. Store it in the collection (not environment) scope, or inline the schema in the test.
Captured body over the free 2 MB limit
Schema limitFree JSON processing caps at 2,000,000 bytes (2 MB). A huge paginated response is far more than the schema needs — capture one page or one record. Pro raises the cap to 100 MB.
Frequently asked questions
Which validator does pm.response.to.have.jsonSchema use?
Tiny Validator (tv4), built into the Postman sandbox. It enforces type, required, and nested properties, but it ignores additionalProperties. The same engine runs in the Collection Runner and Newman.
Why did adding an unexpected key not fail my schema test?
tv4 does not enforce additionalProperties: false, so extra keys pass even though the generated schema sets it. To catch unexpected keys, compile the schema with AJV inside the Tests tab and assert that validate(pm.response.json()) is true.
How do I reuse one schema across many tests?
Paste the generated schema into a collection variable (e.g. GET_USER_SCHEMA), then in each test do const schema = JSON.parse(pm.collectionVariables.get('GET_USER_SCHEMA')); before the assertion. Keep it in collection scope so Newman picks it up.
Does the schema work in Newman and CI?
Yes. Newman runs the same test scripts and the same tv4 validator, so the assertion behaves identically. Just make sure the schema variable is included in the exported collection.
Can I use this for a Postman mock server?
Mock servers return saved Examples, not schema-validated responses. Save your captured body as the request Example for the mock, and use the generated schema in test scripts to assert that live responses still match that shape.
Why does a field that's sometimes null fail the assertion?
A null sample value infers "type":"null", which only matches null. When the API returns a real value the test fails. Edit the schema variable to "type": ["string", "null"] (or the right base type).
Does the schema check date formats or enums?
No. The generator never infers format or enum, so the assertion checks structure and types only. Add format or enum to the schema by hand if you want the test to enforce value rules — but note tv4 has only partial format support.
How do I name the schema?
Set the Schema title field (default MySchema) to something like GetUser200. It is written to the root title only and documents which response the schema describes; it does not affect the assertion result.
Can I get a strict, extra-key-rejecting test?
Use AJV inside the test instead of the built-in matcher: const validate = new Ajv().compile(schema); pm.expect(validate(pm.response.json())).to.be.true;. AJV enforces the additionalProperties: false that tv4 ignores. If you also want TypeScript types for the response, feed the same captured body to the JSON to TypeScript tool.
Is the captured response uploaded to JAD Apps?
No. Schema generation runs entirely in your browser. Production response bodies pasted in for schema generation never reach JAD Apps servers. To compare two captured responses for contract drift before writing the schema, the JSON diff tool highlights added or removed keys.
Why did pasting several responses fail?
The tool parses a single JSON value. Multiple responses (one per line) throw a parse error. Generate from one response object, or wrap them in a [ ... ] array.
What is the free size limit?
2 MB (2,000,000 bytes) per file, one at a time. Pro raises it to 100 MB and 10 files. One captured response is normally a few KB.
Privacy first
Conversion runs locally in your browser. No file is uploaded — only metadata counters are saved for signed-in dashboard stats.