How to Send a POST Request in Python

If you want to send data to an API in Python, a POST request is one of the most common ways to do it.

On this page, you will learn how to:

  • Send a basic POST request in Python
  • Send JSON data to an API
  • Check the status code
  • Read JSON or text responses
  • Avoid common beginner mistakes

Quick answer

import requests

url = "https://httpbin.org/post"
payload = {"name": "Alice", "age": 25}

response = requests.post(url, json=payload)
print(response.status_code)
print(response.json())

Use requests.post() with json= when the API expects JSON data.

Install requests first if needed:

pip install requests

What this page helps you do

This page shows you the practical steps for sending a POST request in Python.

You will learn how to:

  • Send data to a server
  • Use the requests library
  • Send JSON and form data
  • Read the server response
  • Handle common errors safely

When to use a POST request

Use a POST request when you want to send data to a server.

Common examples:

  • Creating a new user
  • Sending form data
  • Logging in
  • Submitting JSON to an API

POST is different from GET because POST sends data in the request body.

If you are new to working with APIs, you may also want to read how to make an API request in Python.

Install and import the requests library

Most beginners use the requests package because it is much simpler than built-in alternatives.

Install it with pip:

pip install requests

If that does not work, try:

python -m pip install requests

Then import it at the top of your Python file:

import requests

If Python says the module does not exist, see how to fix ModuleNotFoundError.

Send a simple POST request with JSON

This is the most common beginner example.

Use requests.post(url, json=data) and pass a Python dictionary.

import requests

url = "https://httpbin.org/post"
data = {
    "name": "Alice",
    "age": 25
}

response = requests.post(url, json=data)

print(response.status_code)
print(response.json())

What this code does

  • url is the API endpoint
  • data is a Python dictionary
  • json=data tells requests to convert the dictionary to JSON
  • response stores the server's reply

A successful response often has a status code like 200 or 201.

Why use json=?

When you use json=, the requests library:

  • Converts your Python dictionary into JSON
  • Sends it in the request body
  • Usually adds the correct Content-Type header for JSON

If you need help understanding JSON data, see how to parse JSON in Python or the Python json module overview.

Check the response

After sending the request, you should always check the response.

Get the status code

print(response.status_code)

This helps you see whether the request worked.

Examples:

  • 200 = OK
  • 201 = Created
  • 400 = Bad request
  • 401 = Unauthorized
  • 404 = Not found
  • 500 = Server error

Read JSON from the response

If the API returns JSON, use:

print(response.json())

Example:

result = response.json()
print(result["json"])

Read plain text instead

If the server returns plain text or HTML, use:

print(response.text)

This is useful when response.json() fails.

If you want more help reading API replies, see how to handle API responses in Python.

Send form data instead of JSON

Some APIs or websites expect form-style data instead of JSON.

In that case, use data= instead of json=.

import requests

url = "https://httpbin.org/post"
form_data = {
    "username": "alice",
    "password": "secret123"
}

response = requests.post(url, data=form_data)

print(response.status_code)
print(response.text)

Important difference

  • Use json= for JSON data
  • Use data= for form data or raw body content

Do not mix them up unless the API documentation tells you to.

Add headers when needed

Some APIs require headers.

Common examples:

  • Authorization
  • Content-Type
  • Accept

You can send headers with the headers= argument.

import requests

url = "https://httpbin.org/post"
data = {"message": "Hello"}

headers = {
    "Authorization": "Bearer your_token_here"
}

response = requests.post(url, json=data, headers=headers)

print(response.status_code)
print(response.json())

If you use json=, requests usually sets the JSON content type for you.

Handle errors safely

Network requests do not always work.

They can fail because of:

  • A bad URL
  • No internet connection
  • A timeout
  • Server errors
  • Missing authentication

A simple beginner-friendly pattern is to use try and except.

import requests

url = "https://httpbin.org/post"
data = {"name": "Alice"}

try:
    response = requests.post(url, json=data, timeout=10)
    response.raise_for_status()

    print("Status:", response.status_code)
    print("Response JSON:", response.json())

except requests.exceptions.RequestException as error:
    print("Request failed:", error)

Why this helps

  • timeout=10 prevents the program from waiting forever
  • raise_for_status() turns HTTP errors into exceptions
  • except requests.exceptions.RequestException catches common request problems

Beginner debugging checklist

If your POST request is not working, check these first:

  • Is the URL correct?
  • Does the API expect json= or data=?
  • Did you install requests?
  • Are you sending the correct field names?
  • Does the API require headers such as Authorization?
  • Did you check the status code?
  • Did you print the response body?

Useful debugging commands:

pip install requests
python -m pip install requests
print(response.status_code)
print(response.text)
print(response.headers)

If response.json() gives an error, print response.text first. The server may have returned HTML or a plain text error message instead of JSON.

Common mistakes

Here are some common causes of POST request problems:

  • Using data= when the API expects JSON
  • Calling response.json() when the server did not return JSON
  • Forgetting to install the requests package
  • Using the wrong URL or endpoint
  • Missing required headers such as Authorization
  • Sending fields with the wrong names
  • Not checking the status code before processing the response

A very common mistake is treating a string like a dictionary after a bad JSON parse step. If that happens, see how to fix TypeError: string indices must be integers or slices.

FAQ

What is the difference between data= and json= in requests.post()?

Use json= to send JSON.

Use data= for form data or raw body content.

Many APIs expect json=.

Do I need to import a special module to send POST requests?

Yes. Beginners usually use the requests library, so you need:

import requests

Why does response.json() fail?

It usually fails when the server returned plain text, HTML, or an error page instead of JSON.

In that case, print:

print(response.text)

You can also learn more from how to parse JSON in Python.

How do I know if the POST request worked?

Check response.status_code.

Codes like 200 or 201 often mean success.

Can I send a POST request without requests?

Yes, with urllib, but requests is much easier for beginners.

See also