Skip to main content

How to Resolve Python "TypeError: 'Response' object is not subscriptable"

When working with HTTP requests in Python using the popular requests library, you might encounter the TypeError: 'Response' object is not subscriptable. This error arises when you attempt to access data within the response using dictionary-style square brackets (response['key']) directly on the Response object returned by requests.get(), requests.post(), etc.

This guide explains why the Response object isn't directly subscriptable and shows the correct way to access JSON response data using the .json() method.

Understanding the Error: Response Object vs. Response Body

When you make a request using requests.get(...) or requests.post(...), the library returns a requests.Response object. This object is a container for the entire HTTP response, including:

  • Status code (response.status_code)
  • Headers (response.headers)
  • Raw content/body (response.content for bytes, response.text for decoded string)
  • Methods to decode common formats (like response.json())
  • And more...

The Response object itself is not the data payload (like a dictionary or list) returned by the server. It's the wrapper around that data and other response metadata. Therefore, you cannot directly access potential dictionary keys using square brackets on the Response object itself.

The Cause: Trying to Index the Response Object Directly

The TypeError occurs because you are treating the Response object as if it were a dictionary or list by using square brackets [...] (the subscription operator).

import requests

# Assume this URL returns JSON like: {"userId": 1, "id": 1, "title": "..."}
url = 'https://jsonplaceholder.typicode.com/todos/1'

try:
print(f"Making GET request to {url}...")
response = requests.get(url, timeout=10)
response.raise_for_status() # Check for HTTP errors

print(f"Response object type: {type(response)}")
# Output: Response object type: <class 'requests.models.Response'>

# Error Scenario: Trying to access 'userId' directly on the Response object
# ⛔️ TypeError: 'Response' object is not subscriptable
user_id = response['userId'] # Incorrect: Response object is not a dictionary
print(f"User ID: {user_id}")

except requests.exceptions.RequestException as e:
print(f"Request Error: {e}")
except TypeError as e:
print(f"Caught Error: {e}") # This is where the error occurs

Python correctly tells you that the Response object doesn't support item access via [].

The Solution: Parse the JSON Body with .json()

If the API you are calling returns data in JSON format (which is very common), the requests library provides a convenient .json() method on the Response object. This method:

  1. Reads the response body.
  2. Attempts to parse the body as JSON.
  3. Returns the parsed data as a standard Python object (usually a dict or list).

Once you have the Python dictionary or list returned by .json(), that object is subscriptable.

import requests

url = 'https://jsonplaceholder.typicode.com/todos/1'

try:
print(f"Making GET request to {url}...")
response = requests.get(url, timeout=10)
response.raise_for_status()

# 1. Call .json() to parse the response body
parsed_data = response.json()

print(f"Parsed data type: {type(parsed_data)}")
# Output: Parsed data type: <class 'dict'>
print(f"Parsed data: {parsed_data}")
# Output: Parsed data: {'userId': 1, 'id': 1, 'title': 'delectus aut autem', 'completed': False}

# 2. Now access keys using square brackets on the PARSED data (the dictionary)
user_id = parsed_data['userId']
title = parsed_data['title']

print(f"\nUser ID: {user_id}") # Output: User ID: 1
print(f"Title: {title}") # Output: Title: delectus aut autem

except requests.exceptions.RequestException as e:
print(f"Request Error: {e}")
except requests.exceptions.JSONDecodeError as e:
# Handle cases where the response body isn't valid JSON
print(f"JSON Decode Error: Response body could not be parsed as JSON - {e}")
print(f"Response text: {response.text[:100]}...") # Show beginning of text
except KeyError as e:
# Handle cases where the expected key is missing in the parsed JSON
print(f"KeyError: Key '{e}' not found in the JSON response.")
except Exception as e:
print(f"An unexpected error occurred: {e}")

Call response.json() first, then use ['key'] on the resulting dictionary. Always consider adding try...except blocks for potential JSONDecodeError (if the response isn't valid JSON) and KeyError (if the expected key isn't in the response).

Example: POST Request

The principle is identical for POST requests that return a JSON response.

import requests

url = 'https://jsonplaceholder.typicode.com/posts'
payload = {'title': 'My Post', 'body': 'This is the content.', 'userId': 5}

try:
print(f"\nMaking POST request to {url}...")
response = requests.post(url, json=payload, timeout=10) # Using json= automatically sets headers
response.raise_for_status()

# 1. Parse the JSON response
parsed_response_data = response.json()
print(f"Parsed POST response: {parsed_response_data}")
# Output: Parsed POST response: {'title': 'My Post', 'body': 'This is the content.', 'userId': 5, 'id': 101}

# 2. Access data from the parsed dictionary
new_post_id = parsed_response_data['id']
print(f"New Post ID: {new_post_id}")
# Output: New Post ID: 101

except requests.exceptions.RequestException as e:
print(f"Request Error: {e}")
except requests.exceptions.JSONDecodeError as e:
print(f"JSON Decode Error: {e}\nResponse text: {response.text[:100]}...")
except KeyError as e:
print(f"KeyError: Key '{e}' not found.")
except Exception as e:
print(f"An unexpected error occurred: {e}")

Why the Error Occurs: Subscriptable Objects

As mentioned, the TypeError: 'X' object is not subscriptable means the object X doesn't support access via []. This requires the object to implement a special method called __getitem__.

  • Subscriptable built-in types: list, tuple, dict, str (they all have __getitem__).
  • Non-subscriptable: Standard objects (like requests.Response), numbers, booleans, None, etc., generally do not implement __getitem__ in a way that allows arbitrary indexing or key lookup.

The response.json() method returns a standard Python dict or list, which are subscriptable.

Conclusion

The TypeError: 'Response' object is not subscriptable arises when using the requests library because you are incorrectly trying to access data using dictionary-style square brackets ([]) directly on the Response object itself.

The correct solution is to first parse the JSON response body into a Python dictionary or list using the response.json() method. You can then use square brackets (parsed_data['key'] or parsed_data[index]) on the resulting Python object.

import requests

response = requests.get("some_api_url")
response.raise_for_status() # Check for errors

# INCORRECT: data = response['some_key']
# CORRECT:
try:
parsed_data = response.json() # Parse first
value = parsed_data['some_key'] # Access the dictionary/list
print(value)
except requests.exceptions.JSONDecodeError:
print("Response was not valid JSON")
except KeyError:
print("Key 'some_key' not found in JSON response")

Remember to handle potential JSONDecodeError and KeyError exceptions for robust code.