Of course! Here is a comprehensive guide on how to make POST requests in Python using the popular requests library.

We'll cover:
- Installation of the
requestslibrary. - Basic
POSTRequest with simple key-value data. - Sending JSON Data (the most common use case for APIs).
- Sending Files via a
POSTrequest. - Handling Headers and Authentication.
- Checking the Response from the server.
- Complete, Runnable Examples you can try yourself.
Installation
First, you need to install the requests library. If you don't have it, open your terminal or command prompt and run:
pip install requests
Basic POST Request (Form Data)
The most basic POST request sends data in the format application/x-www-form-urlencoded, which is what HTML forms typically use. You pass this data as a Python dictionary to the data parameter.
import requests
import json # For pretty-printing the response
# The URL of the API endpoint
url = 'https://httpbin.org/post' # httpbin.org is a great tool for testing requests
# The data to send in the POST request (as a dictionary)
# This will be sent as form data: name=John+Doe&age=30
payload = {
'name': 'John Doe',
'age': 30
}
try:
# Make the POST request
response = requests.post(url, data=payload)
# Raise an exception if the request was unsuccessful (e.g., 404, 500)
response.raise_for_status()
# Print the response content
print("Status Code:", response.status_code)
print("Response JSON:")
# Use json.dumps to format the JSON nicely
print(json.dumps(response.json(), indent=2))
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
What happens here:

requests.post(url, data=payload)sends aPOSTrequest tourl.- The
dataparameter automatically converts the Python dictionary into the correct format for the request body. response.json()parses the JSON response from the server into a Python dictionary.
Sending JSON Data
Modern APIs almost always expect data in JSON format (application/json). To do this, you use the json parameter instead of data. The requests library will automatically handle the serialization and set the correct Content-Type header for you.
import requests
import json
url = 'https://httpbin.org/post'
# The data to send, which will be converted to a JSON string
json_payload = {
'user': 'jane_doe',
'email': 'jane.doe@example.com',
'is_active': True,
'courses': ['Python', 'Data Science']
}
try:
# Make the POST request with the json parameter
response = requests.post(url, json=json_payload)
response.raise_for_status()
print("Status Code:", response.status_code)
print("Response JSON:")
print(json.dumps(response.json(), indent=2))
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
Key Difference:
data: Sends data asapplication/x-www-form-urlencoded. Good for simple forms.json: Sends data asapplication/json. This is the standard for REST APIs.
Sending Files
You can also upload files using a POST request. You do this by passing a dictionary to the files parameter.
import requests
url = 'https://httpbin.org/post'
# Path to the file you want to upload
file_path = 'my_document.txt'
# Open the file in binary read mode
with open(file_path, 'rb') as f:
# The dictionary key ('file') is the name of the form field
# The value is the file object itself
files = {'file': f}
try:
response = requests.post(url, files=files)
response.raise_for_status()
print("Status Code:", response.status_code)
# The response will contain information about the uploaded file
print("Response JSON:")
print(response.json())
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
Handling Headers and Authentication
Often, you need to send custom headers (like Authorization or Content-Type) or authenticate with the server. You can do this using the headers and auth parameters.

import requests
import json
url = 'https://httpbin.org/post'
# Custom headers
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-Custom-Header': 'MyValue'
}
# Data payload
payload = {
'message': 'This request has custom headers and basic auth.'
}
# Basic Authentication (username, password)
# For httpbin.org, 'user' is the username and 'password' is the password
auth = ('user', 'password')
try:
response = requests.post(
url,
json=payload,
headers=headers,
auth=auth
)
response.raise_for_status()
print("Status Code:", response.status_code)
print("Response JSON:")
print(json.dumps(response.json(), indent=2))
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
Checking the Response
After you make a request, the response object contains a lot of useful information.
response.status_code: The HTTP status code (e.g., 200 for OK, 201 for Created, 404 for Not Found, 500 for Server Error).response.text: The response content as a string.response.json(): Parses the response content as JSON (if the content is JSON).response.headers: A dictionary of the response headers.response.request: The originalRequestobject that generated the response.
Best Practice: Always check the status code before trying to access the response content.
response = requests.post('https://httpbin.org/post', json={'key': 'value'})
if response.status_code == 200:
print("Success!")
print(response.json())
elif response.status_code == 404:
print("Resource not found.")
elif response.status_code == 401:
print("Authentication failed.")
else:
print(f"An unexpected error occurred: {response.status_code}")
Complete Runnable Example
Here is a full example combining several concepts. Let's pretend we are creating a new user in a fictional API.
import requests
import json
# 1. Define the API endpoint and data
API_URL = "https://api.example.com/v1/users" # Fictional URL
NEW_USER_DATA = {
"username": "new_test_user",
"email": "newuser@example.com",
"password": "a-very-strong-password"
}
# 2. Define headers (often required for modern APIs)
HEADERS = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": "Bearer YOUR_API_KEY_HERE" # Replace with your actual API key
}
# 3. Make the POST request
try:
print("Sending POST request to create a new user...")
response = requests.post(API_URL, json=NEW_USER_DATA, headers=HEADERS)
# 4. Check the response
print(f"Response Status Code: {response.status_code}")
if response.status_code == 201: # 201 Created is a common success code for POST
print("User created successfully!")
# The response might contain the new user's ID
created_user = response.json()
print("New User Details:")
print(json.dumps(created_user, indent=2))
else:
# Handle different types of errors
print(f"Error: Failed to create user.")
print(f"Status Code: {response.status_code}")
print(f"Response Body: {response.text}")
except requests.exceptions.RequestException as e:
print(f"An error occurred during the request: {e}")
