DEV Community

Nico Reyes
Nico Reyes

Posted on

REST API said 200 OK. Response was 404 JSON.

REST API said 200 OK. Response was 404 JSON.

Spent 2 hours debugging why my API client kept breaking. The third party API returns HTTP 200 for everything. Errors included.

Not a 404 status code. Just {"error": "not found"} wrapped in a success response.

Built a service to pull product data

Standard REST setup. If status is 200, parse the response. Anything else, log the error and bail.

Worked great in testing. Production crashed within 10 minutes.

Logs showed successful requests (200 status). App couldn't find the product ID field. Checked the raw response:

{"error": "Product not found", "code": 404}
Enter fullscreen mode Exit fullscreen mode

HTTP 200. Error in the body.

Some APIs treat status codes as transport only

If the request reached the server and got a response, its a 200. Actual result lives in the JSON body.

Seen this with payment gateways, legacy enterprise APIs, weirdly designed microservices. Not standard but happens more than you'd think.

Stopped trusting status codes

Added response body validation before parsing anything.

import requests

def fetch_product(product_id):
    response = requests.get(f"https://api.vendor.com/products/{product_id}")

    if response.status_code == 200:
        data = response.json()

        # Check for error in body first
        if "error" in data or "code" in data:
            raise Exception(f"API error: {data.get('error', 'unknown')}")

        return data.get("product")

    response.raise_for_status()
Enter fullscreen mode Exit fullscreen mode

Added similar checks for every endpoint. No more surprise crashes.

Now I validate structure before assuming success:

  • error field in body
  • status or code field with failure values
  • Missing expected fields (like product_id)

If any of those exist in a 200 response, treat it as an error.

Started logging full response body on failures too. Helps when APIs do weird stuff like this.

Still annoyed about losing 2 hours to it tho

Top comments (0)