How to Handle API Responses in Python

After you make a request to an API, the next step is handling the response safely.

This means:

  • checking whether the request succeeded
  • reading the returned data
  • handling JSON correctly
  • dealing with errors like bad status codes or invalid response content

This page shows a simple beginner-friendly pattern for working with API responses in Python.

Quick example

import requests

url = "https://api.example.com/data"
response = requests.get(url, timeout=10)

if response.status_code == 200:
    data = response.json()
    print(data)
else:
    print("Request failed:", response.status_code)
    print(response.text)

Use this pattern to check whether the request worked before reading the response data.

What this page covers

  • Handle the data returned by an API request
  • Check whether the request succeeded
  • Read JSON responses safely
  • Deal with common problems like bad status codes or invalid JSON

Check the HTTP status code first

The status code tells you what happened when the server handled your request.

Common examples:

  • 200 usually means success
  • 400 range usually means something was wrong with the request
  • 500 range usually means the server had a problem

Do not assume every response contains usable data. A request can return a response object even when the request failed.

Example:

import requests

response = requests.get("https://api.example.com/data", timeout=10)

print("Status code:", response.status_code)

if response.status_code == 200:
    print("The request worked.")
else:
    print("The request failed.")

If you are new to requests, see how to make an API request in Python.

Read JSON data from the response

Many APIs return data in JSON format.

In Python, you can use response.json() to convert that JSON into normal Python data:

  • a dictionary
  • a list
  • sometimes nested dictionaries and lists

Example:

import requests

response = requests.get("https://api.example.com/user", timeout=10)

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

If the API returns JSON like this:

{
  "name": "Sam",
  "age": 30
}

Then response.json() will usually give you a Python dictionary:

{"name": "Sam", "age": 30}

You can then access values by key:

import requests

response = requests.get("https://api.example.com/user", timeout=10)

if response.status_code == 200:
    data = response.json()
    print(data["name"])

Be careful here. If a key is missing, Python raises a KeyError. For help with that, see KeyError in Python: causes and fixes.

If you want to understand JSON better, see the Python JSON module overview or json.loads() explained.

Handle non-JSON responses

Not every API response contains JSON.

Sometimes the server returns:

  • plain text
  • HTML
  • an error page
  • an empty response

In those cases, response.json() may fail.

Use response.text when you want the raw text content:

import requests

response = requests.get("https://api.example.com/data", timeout=10)

print(response.text)

You can also inspect the Content-Type header to see what kind of data the server returned:

import requests

response = requests.get("https://api.example.com/data", timeout=10)

print(response.headers.get("Content-Type"))

A JSON response often has a content type like:

application/json

If the response is HTML, you might see something like:

text/html

That is a sign that calling response.json() may not be correct.

Handle errors safely

A safer pattern is to check the status code and handle JSON parsing carefully.

Example:

import requests

url = "https://api.example.com/data"

try:
    response = requests.get(url, timeout=10)
    response.raise_for_status()

    data = response.json()
    print("Received data:", data)

except requests.exceptions.HTTPError:
    print("HTTP error:", response.status_code)
    print(response.text)

except requests.exceptions.Timeout:
    print("The request took too long.")

except ValueError:
    print("The response was not valid JSON.")
    print(response.text)

What this code does:

  • timeout=10 stops the program from waiting forever
  • raise_for_status() raises an error for bad status codes like 404 or 500
  • response.json() tries to parse JSON
  • except ValueError handles invalid JSON

Printing response.text is often very helpful when debugging API problems.

If you are sending data to an API, you may also want to read how to send a POST request in Python.

Useful response parts to inspect

These are the most useful parts of a response object:

  • response.status_code for the result code
  • response.text for raw text content
  • response.json() for parsed JSON content
  • response.headers for metadata about the response
  • response.url to see the final URL used

Example:

import requests

response = requests.get("https://api.example.com/data", timeout=10)

print("Status code:", response.status_code)
print("Final URL:", response.url)
print("Headers:", response.headers)
print("Text:", response.text)

Use response.json() only when you expect valid JSON.

Beginner workflow for handling API responses

A simple workflow is:

  1. Send the request
  2. Check the status code
  3. If successful, read the data
  4. If not successful, inspect the error message
  5. Handle missing keys or unexpected data carefully

Example:

import requests

response = requests.get("https://api.example.com/user", timeout=10)

if response.status_code == 200:
    try:
        data = response.json()
        print("User name:", data.get("name"))
    except ValueError:
        print("The server did not return valid JSON.")
        print(response.text)
else:
    print("Request failed with status:", response.status_code)
    print(response.text)

This version uses data.get("name") instead of data["name"].

That is useful because get() returns None if the key does not exist, instead of raising an error.

Common mistakes

These are common causes of API response problems:

  • Calling response.json() when the server returned HTML or plain text
  • Ignoring the status code and assuming the request worked
  • Trying to access dictionary keys that do not exist
  • Forgetting to set a timeout
  • Not handling failed requests before using the response data

Useful things to print while debugging:

print(response.status_code)
print(response.text)
print(response.headers)
print(response.url)
print(response.json())

Be careful with print(response.json()). Only use it when you are reasonably sure the response contains valid JSON.

If you treat a string like a dictionary by mistake, you may run into TypeError: string indices must be integers or slices.

FAQ

What is an API response in Python?

It is the data and status information returned after your Python code sends a request to an API.

How do I know if an API request worked?

Check response.status_code. A 200 status code usually means success.

Why does response.json() fail?

It fails when the response does not contain valid JSON, such as HTML error text or plain text.

Should I use response.text or response.json()?

Use response.json() for JSON APIs. Use response.text when the response is plain text or when debugging.

See also