How to Validate API Responses Using JSON Tools
Receiving a 200 OK response does not guarantee that an API returned correct or usable data.
An API response can fail in several ways:
- The body is not valid JSON
- The
Content-Typeis incorrect - Required fields are missing
- Values have unexpected data types
- A response violates its documented contract
- The syntax is valid, but the business data is impossible
- An error response uses a completely different structure
- A third-party API introduces an unexpected change
Formatting a response can make it easier to read, but formatting alone does not prove that the response is correct.
A reliable API validation workflow should examine four separate layers:
- HTTP response metadata
- JSON syntax
- JSON structure and data types
- Business and application rules
This guide explains how to validate each layer using formatters, browser tools, command-line utilities, JSON Schema, and automated tests.
What Is an API Response?
An API response is the message a server returns after processing an HTTP request.
A response normally contains:
- An HTTP status code
- Response headers
- An optional response body
For example:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Cache-Control: no-store{
"id": 101,
"name": "Alice",
"email": "alice@example.com",
"active": true
}The status code describes the outcome, the headers provide metadata, and the body contains the returned representation.
Validation should include all three. Looking only at the JSON body can hide problems with status codes, caching, content negotiation, or media types.
The Four Levels of API Response Validation
API validation is easier when each concern is handled separately.
Level 1: Transport and HTTP validation
Check whether:
- The expected status code was returned
- The response uses HTTPS
- The
Content-Typeis correct - Redirect behavior is expected
- Authentication headers are handled correctly
- Caching headers are appropriate
- The response arrived within an acceptable time
Level 2: JSON syntax validation
Check whether the body is valid JSON.
This detects errors such as:
- Trailing commas
- Missing commas
- Unclosed strings
- Mismatched braces
- Invalid escape sequences
- Unquoted property names
- Unsupported values such as
NaNorundefined
JSON has a strict grammar defined by RFC 8259, and interoperable JSON exchanged outside a closed system must use UTF-8.
Level 3: Schema validation
Check whether the parsed value has the expected shape.
For example:
- Is the root value an object?
- Is
idrequired? - Is
pricea number? - Is
statusrestricted to known values? - Does each array item follow the expected structure?
- Are unknown properties permitted?
Level 4: Semantic validation
Check whether the data makes sense to the application.
For example:
- Is the end date after the start date?
- Is the product price non-negative?
- Does the referenced customer exist?
- Can the current user access this record?
- Does the currency match the account?
- Is a supposedly unique identifier actually unique?
A response can pass JSON syntax and schema validation while still containing invalid business data.
Why Formatting Is Not Validation
Consider this response:
{
"id": "101",
"name": "Alice",
"active": "true"
}It is perfectly valid JSON. A formatter will display it without errors.
However, an application may expect:
{
"id": 101,
"name": "Alice",
"active": true
}The first response uses strings for id and active; the second uses a number and a Boolean.
A JSON formatter answers:
Can this value be displayed in a readable format?
A syntax validator answers:
Does this text follow JSON grammar?
A schema validator answers:
Does this value match the agreed structure and data types?
These are different operations.
Step 1: Verify the HTTP Status Code
Start by checking the response status.
Common successful status codes include:
200 OK: request succeeded201 Created: a new resource was created202 Accepted: processing was accepted but may not be complete204 No Content: request succeeded without a response body
Common client and server error codes include:
400 Bad Request401 Unauthorized403 Forbidden404 Not Found409 Conflict422 Unprocessable Content429 Too Many Requests500 Internal Server Error503 Service Unavailable
HTTP status codes have defined semantics. APIs should not return 200 OK for every outcome and place the actual error only in the JSON body.
Validate the response body against its status
A 204 No Content response should not be treated like a normal JSON document.
Likewise, a 404 response may use an error schema rather than the successful response schema.
For example:
{
"type": "https://api.example.com/problems/not-found",
"title": "Resource not found",
"status": 404,
"detail": "No user exists with ID 101"
}Validate success and error responses separately.
Step 2: Check the Content-Type Header
For a standard JSON response, the media type should normally be:
Content-Type: application/jsonProblem-detail responses may use:
Content-Type: application/problem+jsonDo not assume every response is JSON simply because the endpoint normally returns JSON.
A proxy, authentication gateway, or web server could instead return:
<html>
<body>Service unavailable</body>
</html>Attempting to parse that body as JSON produces a parsing error that hides the actual server problem.
JavaScript example
async function requestJson(url, options = {}) {
const response = await fetch(url, options);
const contentType = response.headers.get("content-type") || "";
if (!contentType.includes("application/json")) {
const body = await response.text();
throw new Error(
`Expected JSON but received "${contentType}". ` +
`Status: ${response.status}. Body: ${body.slice(0, 200)}`
);
}
const data = await response.json();
if (!response.ok) {
throw new Error(
data.detail || data.message || `HTTP ${response.status}`
);
}
return data;
}The Fetch API does not reject its promise merely because the server returned an HTTP error status. Applications should check response.ok or response.status explicitly.
Step 3: Validate JSON Syntax
A syntax validator confirms that the response can be parsed as JSON.
Valid JSON
{
"id": 101,
"name": "Alice",
"roles": ["editor", "author"]
}Invalid JSON
{
"id": 101,
"name": "Alice",
"roles": ["editor", "author"],
}The trailing comma is not allowed.
Common JSON syntax errors
Single-quoted strings
Invalid:
{'name': 'Alice'}Valid:
{
"name": "Alice"
}Unquoted property names
Invalid:
{name: "Alice"}Valid:
{
"name": "Alice"
}JavaScript-only values
Invalid JSON:
{
"discount": undefined,
"score": NaN
}JSON supports only:
- Objects
- Arrays
- Strings
- Numbers
truefalsenull
Comments
Invalid:
{
// Current user
"name": "Alice"
}Standard JSON does not support comments.
Step 4: Format the Response for Inspection
Minified responses are efficient to transmit but difficult to inspect.
Minified JSON:
{"id":101,"name":"Alice","permissions":["read","write"]}Formatted JSON:
{
"id": 101,
"name": "Alice",
"permissions": [
"read",
"write"
]
}Formatting helps reveal:
- Unexpected nesting
- Duplicate-looking objects
- Empty arrays
- Missing properties
- Inconsistent names
- Unexpected
nullvalues - Oversized embedded data
Format JSON in JavaScript
const formatted = JSON.stringify(data, null, 2);
console.log(formatted);Format JSON with Python
python -m json.tool response.jsonFormat JSON with jq
jq . response.jsonTo extract selected values:
jq '.users[] | {id, email, status}' response.jsonFormatting improves visibility, but it should be followed by structural validation.
Step 5: Define the Expected Response Contract
Before validating a response, define what the API is expected to return.
For example, a user endpoint may require:
| Property | Type | Required | Rules |
|---|---|---|---|
id | Integer | Yes | At least 1 |
name | String | Yes | 1–100 characters |
email | String | Yes | Valid application format |
active | Boolean | Yes | true or false |
roles | Array | Yes | Unique strings |
avatarUrl | String or null | No | Valid permitted URL |
Without an explicit contract, developers tend to validate responses according to assumptions rather than documented requirements.
Contracts can be represented using:
- JSON Schema
- OpenAPI
- Runtime validation libraries
- Typed application models
- Consumer-driven contracts
Step 6: Validate the Response with JSON Schema
JSON Schema describes the expected structure and constraints of a JSON value.
The current JSON Schema specification is organized into vocabularies covering validation, core behavior, applicators, metadata, and other features.
A schema for the user response might look like this:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://api.example.com/schemas/user.json",
"title": "User response",
"type": "object",
"required": [
"id",
"name",
"email",
"active",
"roles"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"email": {
"type": "string",
"format": "email"
},
"active": {
"type": "boolean"
},
"roles": {
"type": "array",
"items": {
"type": "string",
"enum": [
"reader",
"editor",
"administrator"
]
},
"uniqueItems": true
},
"avatarUrl": {
"type": [
"string",
"null"
],
"format": "uri"
}
},
"additionalProperties": false
}This schema checks:
- The root is an object
- Required properties exist
idis a positive integeractiveis a Booleanrolesis an array- Role values belong to an approved list
- Duplicate roles are rejected
- Undocumented properties are rejected
Decide how to handle unknown properties
This setting is important:
{
"additionalProperties": false
}It rejects fields not declared in properties.
That is useful for detecting accidental contract changes, but it may also break forward compatibility when a server adds harmless fields.
Choose a policy intentionally:
- Reject unknown properties for strict internal contracts
- Allow them when clients must tolerate additive API changes
- Log them during migrations
- Restrict only security-sensitive objects
Step 7: Use a Schema Validator in JavaScript
A JSON Schema validator can compile a schema and test responses at runtime.
The following conceptual example uses Ajv:
import Ajv from "ajv";
const ajv = new Ajv({
allErrors: true,
strict: true
});
const validateUser = ajv.compile(userSchema);
function assertValidUserResponse(data) {
const valid = validateUser(data);
if (!valid) {
console.error(validateUser.errors);
throw new Error("API response failed schema validation");
}
return data;
}Usage:
const response = await fetch("/api/users/101");
const data = await response.json();
const user = assertValidUserResponse(data);
console.log(user.name);Ajv compiles JSON Schemas into validation functions and provides structured error information when values do not match.
Do not silently ignore validation failures
In development and automated testing, failed validation should normally fail loudly.
In production, your strategy may include:
- Rejecting the response
- Displaying a safe fallback
- Recording telemetry
- Disabling the affected component
- Retrying when appropriate
- Reporting the contract violation
Avoid exposing raw internal validation details to end users.
Step 8: Validate Nested Objects and Arrays
Nested responses require rules at every level.
Example response:
{
"orderId": 5001,
"customer": {
"id": 101,
"name": "Alice"
},
"items": [
{
"productId": 84,
"quantity": 2,
"unitPrice": 19.95
}
]
}A useful schema should validate:
- The
customerobject - Required customer fields
- Every item in the
itemsarray - Minimum array length
- Positive quantities
- Non-negative prices
Example:
{
"type": "object",
"required": ["orderId", "customer", "items"],
"properties": {
"orderId": {
"type": "integer",
"minimum": 1
},
"customer": {
"type": "object",
"required": ["id", "name"],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"name": {
"type": "string",
"minLength": 1
}
}
},
"items": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": [
"productId",
"quantity",
"unitPrice"
],
"properties": {
"productId": {
"type": "integer",
"minimum": 1
},
"quantity": {
"type": "integer",
"minimum": 1
},
"unitPrice": {
"type": "number",
"minimum": 0
}
}
}
}
}
}Never validate only the outer object while trusting nested values automatically.
Step 9: Handle Missing, Null, and Empty Values Separately
These values are not interchangeable:
Missing property
{}Explicit null
{
"profile": null
}Empty object
{
"profile": {}
}Empty array
{
"roles": []
}Empty string
{
"displayName": ""
}Your contract should define which states are allowed.
For example:
{
"avatarUrl": {
"type": ["string", "null"]
}
}This permits a string or null, but the property can still be required:
{
"required": ["avatarUrl"]
}A required nullable property is different from an optional property.
Step 10: Validate Error Responses
Many applications validate only successful responses.
Error responses need contracts too.
A consistent error object might contain:
{
"type": "https://api.example.com/problems/validation-error",
"title": "Request validation failed",
"status": 422,
"errors": [
{
"field": "email",
"code": "invalid_format",
"message": "Enter a valid email address"
}
],
"requestId": "req_92e773"
}Validate that error responses include:
- A stable error type or code
- An appropriate HTTP status
- A safe user-facing message
- Field-level details where applicable
- A request or correlation identifier
- No stack traces, queries, secrets, or internal paths
Different status codes may require different error schemas.
Step 11: Compare Responses During API Changes
When an API changes, a JSON diff can identify structural differences.
Old response:
{
"id": 101,
"name": "Alice"
}New response:
{
"id": 101,
"fullName": "Alice"
}The rename from name to fullName is a breaking change for clients expecting the original property.
Changes that may break consumers
- Removing a property
- Renaming a property
- Changing a data type
- Making an optional field required
- Changing
nullbehavior - Changing an enum value
- Altering nested structure
- Changing identifier formats
Adding a new property is usually safer, but strict clients that reject unknown fields may still fail.
Use schema comparison and contract testing rather than relying only on visual JSON diffs.
Step 12: Validate APIs Documented with OpenAPI
OpenAPI can describe:
- Endpoints
- Methods
- Parameters
- Request bodies
- Status codes
- Response headers
- Response schemas
- Authentication requirements
An OpenAPI response definition might look like this:
responses:
"200":
description: User retrieved successfully
content:
application/json:
schema:
$ref: "#/components/schemas/User"
"404":
description: User not found
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"OpenAPI 3.1 aligns its Schema Object more closely with JSON Schema Draft 2020-12, although OpenAPI still defines additional API-specific behavior.
An OpenAPI document can support:
- Documentation generation
- Client generation
- Mock servers
- Request validation
- Response validation
- Contract tests
The document is valuable only when it stays synchronized with the implementation.
Step 13: Inspect Responses in Browser DevTools
For browser applications:
- Open Chrome DevTools.
- Select the Network panel.
- Perform the action that calls the API.
- Select the request.
- Inspect Headers.
- Review the Payload when applicable.
- Inspect Preview and Response.
- Check timing and initiator information.
Verify:
- Request URL
- HTTP method
- Status code
- Redirects
- Request headers
- Response headers
- Content type
- Raw response body
- Response duration
The formatted Preview tab is convenient, but check the raw Response tab when diagnosing malformed data.
Step 14: Validate from the Command Line
Command-line tools help reproduce API behavior independently of frontend code.
Save a response with curl
curl \
--silent \
--show-error \
--fail-with-body \
--output response.json \
https://api.example.com/users/101Display response headers
curl \
--include \
https://api.example.com/users/101Validate and format with jq
jq . response.jsonIf the file contains invalid JSON, jq exits with an error.
Extract selected properties
jq '{
id,
name,
active,
roles
}' response.jsonAssert a basic condition
jq -e '
(.id | type == "number") and
(.name | type == "string") and
(.active | type == "boolean")
' response.jsonFor complex contracts, use a real JSON Schema validator rather than building an entire validation system with ad hoc jq expressions.
Step 15: Add Response Validation to Automated Tests
Manual tools are useful during debugging, but they cannot prevent future regressions.
Automated tests should cover:
Successful responses
- Correct status code
- Correct media type
- Required fields
- Data types
- Allowed values
- Nested structures
Error responses
- Authentication failures
- Authorization failures
- Missing resources
- Invalid request data
- Rate limits
- Internal errors
Boundary conditions
- Empty arrays
- Null values
- Maximum-length strings
- Pagination boundaries
- Missing optional fields
- Unicode content
- Large responses
Example test structure
test("GET /users/:id returns a valid user", async () => {
const response = await fetch(
"https://api.example.com/users/101"
);
expect(response.status).toBe(200);
expect(
response.headers.get("content-type")
).toContain("application/json");
const data = await response.json();
expect(validateUser(data)).toBe(true);
});Run contract validation in CI so incompatible changes are detected before deployment.
Step 16: Add Semantic Business Checks
JSON Schema is powerful, but it cannot conveniently express every business rule.
Suppose an API returns:
{
"startDate": "2026-10-10",
"endDate": "2026-10-01"
}Both properties may pass string and date-format checks, but the date range is logically invalid.
Additional application validation might be:
function validateDateRange(data) {
const start = new Date(data.startDate);
const end = new Date(data.endDate);
if (end < start) {
throw new Error(
"endDate must not be earlier than startDate"
);
}
}Other semantic checks include:
- Totals equal the sum of line items
- Currency values match
- Referenced records exist
- User and tenant identifiers agree
- Status transitions are permitted
- Pagination metadata is consistent
- Timestamps follow the expected ordering
Schema validation complements business validation; it does not replace it.
Security Considerations
API responses may contain confidential information.
Avoid pasting production responses into unknown tools
An online formatter may receive:
- Access tokens
- Customer records
- Email addresses
- Internal identifiers
- Financial data
- Debug information
Before using a third-party tool:
- Remove credentials
- Redact personal data
- Remove session cookies
- Replace real identifiers
- Confirm how the tool processes and retains input
For sensitive data, prefer:
- A trusted local tool
- Browser DevTools
jq- An approved internal validator
- An editor extension that works offline
Treat external API data as untrusted
Even data returned by another server should be validated before being used in:
- HTML output
- SQL operations
- File paths
- Redirect URLs
- Shell commands
- Authorization decisions
Validation does not replace context-specific output encoding or parameterized queries.
A Production-Ready API Response Checklist
HTTP
- Expected status code is returned
- Correct
Content-Typeheader is returned - Redirect behavior is verified
- Caching policy is reviewed
- Response time is measured
JSON Syntax
- Response parses successfully
- UTF-8 content is tested
- Malformed responses are handled
- Empty-body behavior is defined
Schema
- Root data type is validated
- Required fields are checked
- Property data types are checked
- Nested objects are validated
- Array items are validated
- Null-value behavior is defined
- Enum values are restricted
- Unknown-property policy is documented
Application Rules
- Dates are semantically valid
- Numeric values fall within acceptable ranges
- Cross-field rules are checked
- Identifiers belong to the expected user or tenant
- Authorization is enforced separately
Error Handling
- Error responses have a documented schema
- Error messages do not expose internal details
- Request IDs are returned or logged
- Authentication and rate-limit errors are tested
- Non-JSON server errors are handled
Delivery
- Schemas are stored in version control
- Contract tests run in CI
- Breaking changes are detected
- Third-party API responses are monitored
- Sensitive response data is never copied into untrusted tools
How MyToolForge Can Fit into the Workflow
A JSON formatter and syntax validator is useful for the first stages of API debugging.
You can use it to:
- Format minified responses
- Detect malformed JSON
- Inspect nested data
- Search for unexpected values
- Prepare sanitized examples for bug reports
If the tool does not accept a JSON Schema, describe it as a formatter and syntax validator, not a complete API contract validator.
A practical workflow is:
- Capture the response in DevTools or with
curl. - Remove credentials and personal information.
- Format and inspect the JSON.
- Confirm that it parses correctly.
- Validate it against a version-controlled schema.
- Apply application-specific business checks.
- Add the case to automated tests.
Frequently Asked Questions
Does valid JSON mean an API response is correct?
No. Valid JSON can still contain missing properties, incorrect types, invalid values, or unauthorized data.
Is pretty-printing the same as validation?
No. Pretty-printing changes presentation. Validation checks syntax, structure, or application rules.
Should frontend applications validate API responses?
Validation is especially useful at trust boundaries, when consuming third-party APIs, and when backend contracts change independently. The server must still validate its own data and authorization decisions.
Should unknown response properties be rejected?
It depends on the compatibility policy. Rejecting them detects unexpected changes, but allowing them can make clients more tolerant of additive API updates.
Can JSON Schema validate every business rule?
No. Cross-record checks, database relationships, authorization, and many cross-field rules require application logic.
Final Thoughts
Reliable API response validation involves more than pasting JSON into a formatter.
A complete process verifies:
- HTTP status and headers
- JSON syntax
- Response structure
- Property data types
- Nested objects and arrays
- Null and optional-value behavior
- Error-response contracts
- Business rules
- Security and authorization requirements
- Compatibility through automated contract tests
JSON tools are excellent for inspection and syntax debugging. JSON Schema and OpenAPI make expectations explicit, while automated tests ensure those expectations continue to hold as an API evolves.
The key principle is:
Format API responses to understand them, validate them to trust their structure, and test them continuously to prevent regressions.
Try Next
Other utilities you might find helpful
Regex Tester
Test and debug regular expressions with live matches.
Regex Debugger
Understand regex step-by-step with explanations.
JSON Formatter
Format, validate, and minify JSON instantly.
Base64 Encoder/Decoder
Encode and decode Base64 strings and files.
SQL Explain Parser
Analyze SQL execution plans and optimize queries.
DOM Complexity Analyzer
Analyze HTML DOM structure, detect deep nesting, count nodes, and identify performance issues instantly.