DEV Community

Cover image for How to Debug Large JSON API Responses Faster (With a Practical Example)
ToolZenhub
ToolZenhub

Posted on

How to Debug Large JSON API Responses Faster (With a Practical Example)

Debugging a JSON API response is not always difficult because of the code.

Sometimes the real problem is simply finding the information you need.

Imagine receiving a response containing hundreds of nested objects, arrays, user records, and metadata fields — all compressed into one long line.

You need to identify one unexpected value, confirm the JSON is valid, and decide whether the problem is with the API response or your application.

How do you investigate without wasting time?

Let's work through a practical example.

1. The problem: A difficult-to-read API response

Imagine you're testing an order-management API.

The endpoint returns the following response:

{"orderId":"ORD-1024","customer":{"id":42,"name":"Alex","address":{"city":"Hyderabad","postalCode":"500001"}},"items":[{"sku":"KB-101","quantity":2,"price":1499},{"sku":"MS-202","quantity":1,"price":799}],"payment":{"status":"completed","amount":3797},"delivery":{"status":"pending","estimatedDays":3}}
Enter fullscreen mode Exit fullscreen mode

This response is valid JSON.

But it's not particularly convenient to inspect.

Suppose your API test fails because the expected delivery status is shipped, while the actual response contains pending.

You know something is different, but navigating a large one-line response can be frustrating.

When responses become significantly larger, the problem grows.

Before writing more debugging code, the first useful step is to make the response readable.

2. Format the JSON before investigating

The same response becomes easier to understand when formatted with indentation.

{
  "orderId": "ORD-1024",
  "customer": {
    "id": 42,
    "name": "Alex",
    "address": {
      "city": "Hyderabad",
      "postalCode": "500001"
    }
  },
  "items": [
    {
      "sku": "KB-101",
      "quantity": 2,
      "price": 1499
    },
    {
      "sku": "MS-202",
      "quantity": 1,
      "price": 799
    }
  ],
  "payment": {
    "status": "completed",
    "amount": 3797
  },
  "delivery": {
    "status": "pending",
    "estimatedDays": 3
  }
}
Enter fullscreen mode Exit fullscreen mode

Now you can quickly identify:

  • The order identifier.
  • The customer's information.
  • The array containing purchased items.
  • The payment status and amount.
  • The delivery status.

Formatting doesn't change the underlying data. It changes how easily a developer can inspect its structure.

For a single response, this may save only a little time.

For repeated debugging, readable payloads can make investigations much easier.

3. Inspect nested values using JavaScript

Formatting is useful for visual inspection.

But automated tests need a repeatable way to access specific values.

Suppose the previous response has already been parsed into a JavaScript object named order.

You can inspect individual properties:

console.log(order.orderId);

console.log(order.customer.address.city);

console.log(order.payment.status);

console.log(order.delivery.status);
Enter fullscreen mode Exit fullscreen mode

Expected output:

ORD-1024
Hyderabad
completed
pending
Enter fullscreen mode Exit fullscreen mode

You can also access array values:

console.log(order.items[0].sku);
// KB-101

console.log(order.items[1].quantity);
// 1
Enter fullscreen mode Exit fullscreen mode

For an API tester, this is often the next step after understanding the payload structure.

But there is an important distinction:

Formatting JSON helps you understand the data. Assertions help you verify its behavior.

You need both when debugging a real API.

4. Identify the actual cause of a failed assertion

Consider this Playwright API test:

const { test, expect } = require("@playwright/test");

test("order delivery status", async ({ request }) => {
  const response = await request.get("/api/orders/ORD-1024");

  expect(response.ok()).toBeTruthy();

  const order = await response.json();

  expect(order.delivery.status).toBe("shipped");
});
Enter fullscreen mode Exit fullscreen mode

This test assumes that a configured API endpoint exists and returns the illustrated response.

If the API returns:

{
  "delivery": {
    "status": "pending"
  }
}
Enter fullscreen mode Exit fullscreen mode

The assertion fails.

That failure does not automatically prove the API is defective.

You need to investigate the expected business behavior.

For example:

  • Should a newly created order already be shipped?
  • Is the test running before the delivery update finishes?
  • Does the test use the correct order identifier?
  • Is the response stale or cached?
  • Is pending actually the correct state?

This is where good API testing goes beyond checking individual field values.

A failing assertion is evidence of a mismatch between expectations and actual behavior. It is not, by itself, evidence of a backend defect.

5. What if the response is invalid JSON?

Now consider a different response:

{
  "orderId": "ORD-1024",
  "status": "pending",
}
Enter fullscreen mode Exit fullscreen mode

The trailing comma makes this invalid JSON.

JavaScript's JSON.parse() will throw an error:

const responseText = `{
  "orderId": "ORD-1024",
  "status": "pending",
}`;

try {
  const order = JSON.parse(responseText);
  console.log(order);
} catch (error) {
  console.error("JSON parsing failed:", error.message);
}
Enter fullscreen mode Exit fullscreen mode

A parsing error means the text does not follow JSON syntax.

However, it doesn't tell you whether the original problem came from the backend, a copied sample, a test fixture, or some other source.

First identify where the invalid text originated.

Then correct the responsible system or test data.

Avoid automatically modifying an API response merely to make it parse successfully. Doing so can hide genuine defects.

6. A practical browser-based debugging workflow

For JSON that is safe to inspect locally, a browser-based formatter can reduce the need to write temporary formatting scripts.

I maintain ToolZenHub, a collection of practical online utilities.

One of its developer tools is the free JSON Formatter & Validator:

https://toolzenhub.in/tools/json-formatter/

Here's how you can use it with the earlier order response.

Step 1: Copy the JSON payload

Take the one-line response from the first example.

Make sure you are copying the actual JSON response body rather than headers or unrelated console output.

Step 2: Paste it into the tool

Open the JSON Formatter & Validator and paste the response into its input field.

Step 3: Select Format

The tool formats valid JSON using two-space indentation.

This makes nested objects and arrays easier to inspect.

Step 4: Inspect the relevant fields

In our example, look for:

"delivery": {
  "status": "pending",
  "estimatedDays": 3
}
Enter fullscreen mode Exit fullscreen mode

You can now focus on the property involved in the failing assertion.

Step 5: Validate suspicious JSON

If the payload fails to parse, select Validate.

For malformed JSON, the tool reports the error location, including line and column information.

You can use its "Go to error" option to navigate to the problematic location.

The tool identifies syntax problems; it does not silently repair or rewrite invalid JSON.

Step 6: Copy the formatted result when needed

If you need a readable sample for documentation or a test fixture, use Copy output.

For a compact representation, use Minify instead.

These operations serve different purposes:

Operation Purpose
Format Improve readability
Minify Remove unnecessary whitespace
Validate Check JSON syntax
Copy output Reuse the processed text

The tool processes JSON in your browser rather than uploading it to ToolZenHub.

Still, follow your organization's data-handling policies. Do not paste confidential production data, credentials, tokens, or personal information into tools unless your security requirements permit it.

7. An important limitation: Valid JSON can still contain wrong data

Suppose the API returns:

{
  "orderId": "ORD-1024",
  "payment": {
    "status": "completed",
    "amount": "3797"
  }
}
Enter fullscreen mode Exit fullscreen mode

This is valid JSON.

A syntax validator should accept it.

But notice that amount is a string.

If the API contract requires a number, this response may be incorrect.

For example:

const order = {
  orderId: "ORD-1024",
  payment: {
    status: "completed",
    amount: "3797"
  }
};

console.log(typeof order.payment.amount);
// string
Enter fullscreen mode Exit fullscreen mode

To validate the value's type:

if (typeof order.payment.amount !== "number") {
  throw new Error("Payment amount must be numeric");
}
Enter fullscreen mode Exit fullscreen mode

This is a separate type check.

JSON formatting and syntax validation do not replace schema validation, application logic, or automated assertions.

A useful debugging workflow should distinguish these different responsibilities.

8. Calculate expected values instead of trusting the response

Let's examine the order items:

const items = [
  {
    sku: "KB-101",
    quantity: 2,
    price: 1499
  },
  {
    sku: "MS-202",
    quantity: 1,
    price: 799
  }
];
Enter fullscreen mode Exit fullscreen mode

We can independently calculate the total:

const total = items.reduce((sum, item) => {
  return sum + item.quantity * item.price;
}, 0);

console.log(total);
// 3797
Enter fullscreen mode Exit fullscreen mode

For this example:

2 × 1499 = 2998
1 × 799  = 799

Total = 3797
Enter fullscreen mode Exit fullscreen mode

This gives the tester an independent expected result.

We can compare that result with the returned payment amount.

const actualPaymentAmount = 3797;

if (total !== actualPaymentAmount) {
  throw new Error("Payment amount mismatch");
}
Enter fullscreen mode Exit fullscreen mode

For real payment systems, also account for discounts, taxes, shipping, currency, refunds, and the application's rounding rules.

A simple item-total calculation should not be treated as a universal payment-validation formula.

9. Avoid logging sensitive API responses

A common debugging habit is to print the entire response:

console.log(order);
Enter fullscreen mode Exit fullscreen mode

That may be convenient in a local test.

But production API responses can contain:

  • Authentication credentials.
  • Session tokens.
  • Personal information.
  • Addresses and contact details.
  • Internal identifiers.
  • Confidential application data.

Instead, log only the fields required for investigation.

console.log({
  orderId: order.orderId,
  deliveryStatus: order.delivery.status
});
Enter fullscreen mode Exit fullscreen mode

Even selected identifiers should be checked against your organization's logging policies.

When sharing debugging examples publicly, use fabricated test data rather than real customer information.

10. When should you use a formatter and when should you write code?

Both approaches are useful.

Use a JSON formatter when:

  • You want to visually inspect a response.
  • A nested structure is difficult to read.
  • You need to locate a JSON syntax problem.
  • You want a formatted sample for documentation.
  • You need to remove unnecessary whitespace.

Use automated validation and assertions when:

  • You're checking API behavior repeatedly.
  • The API contract specifies required fields.
  • You need to verify data types.
  • You need to test calculations or business logic.
  • You want failures detected automatically in CI.

For large or sensitive datasets, local command-line tools and approved development environments may be more appropriate than a browser utility.

ToolZenHub's formatter has defined input-size and nesting limits, so it is not intended to process arbitrarily large responses.

The two approaches complement each other rather than compete.

11. A repeatable API debugging checklist

The next time an API test fails, work through these questions:

  1. Did the HTTP request reach the expected endpoint?
  2. Was the HTTP status what you expected?
  3. Is the response body valid JSON?
  4. Is the response structure readable?
  5. Does the expected property exist?
  6. Is the property using the correct data type?
  7. Does the returned value match the API contract?
  8. Are there timing, authentication, or test-data issues?
  9. Can you independently verify the important calculation or result?
  10. Are your debugging logs safe to retain or share?

This sequence helps distinguish syntax issues from data issues and actual application defects.

Final thoughts

Debugging APIs efficiently is not about using the most tools or writing the most code.

It's about reducing uncertainty.

Start by understanding the response. Make the structure readable. Check syntax. Inspect relevant properties. Verify the contract. Then investigate the behavior that caused the test to fail.

If formatting or validating JSON is slowing down your workflow, you can try the browser-based utility I maintain at ToolZenHub:

https://toolzenhub.in/tools/json-formatter/

The goal is simple: spend less time untangling raw payloads and more time identifying the actual problem.


Disclosure: I maintain ToolZenHub, the website referenced in this article. This tutorial was prepared with AI assistance and requires editorial and technical review before publication.

Top comments (0)