Short answer
This is because params sends the parameters as part of the http POST request, while data sends them as part of the body of the request. In your case: just call the api using params and you're fine. This is absolutely normal (and expected) behaviour.

Demonstration
Just start two commandlines. On the first, run netcat: nc -l 8888. On the other commandline, run python:

>>> import requests
>>> requests.post('http://localhost:8888',data={'a':1,'b':'2'})

At the netcat-side, we see the following request:

POST / HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: python-requests/2.18.1
Content-Length: 7
Content-Type: application/x-www-form-urlencoded

a=1&b=2

Next, try the params way:

>>> requests.post('http://localhost:8888',params={'a':1,'b':'2'})

Netcat reports:

POST /?a=1&b=2 HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: python-requests/2.18.1
Content-Length: 0

Note the differences in the first and last line.

As you can read from the documentation (italic emphasis is mine):

params -- (optional) Dictionary or bytes to be sent in the query string for the Request.
data -- (optional) Dictionary or list of tuples [(key, value)] (will be form-encoded), bytes, or file-like object to send in the body of the Request.

Answer from agtoever on Stack Overflow

Short answer
This is because params sends the parameters as part of the http POST request, while data sends them as part of the body of the request. In your case: just call the api using params and you're fine. This is absolutely normal (and expected) behaviour.

Demonstration
Just start two commandlines. On the first, run netcat: nc -l 8888. On the other commandline, run python:

>>> import requests
>>> requests.post('http://localhost:8888',data={'a':1,'b':'2'})

At the netcat-side, we see the following request:

POST / HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: python-requests/2.18.1
Content-Length: 7
Content-Type: application/x-www-form-urlencoded

a=1&b=2

Next, try the params way:

>>> requests.post('http://localhost:8888',params={'a':1,'b':'2'})

Netcat reports:

POST /?a=1&b=2 HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: python-requests/2.18.1
Content-Length: 0

Note the differences in the first and last line.

As you can read from the documentation (italic emphasis is mine):

params -- (optional) Dictionary or bytes to be sent in the query string for the Request.
data -- (optional) Dictionary or list of tuples [(key, value)] (will be form-encoded), bytes, or file-like object to send in the body of the Request.

Answer from agtoever on Stack Overflow
🌐
Requests
requests.readthedocs.io › en › latest › user › quickstart
Quickstart — Requests 2.34.0 documentation
Requests’ simple API means that all forms of HTTP request are as obvious. For example, this is how you make an HTTP POST request:
🌐
W3Schools
w3schools.com › python › ref_requests_post.asp
Python Requests post Method
Python Examples Python Compiler ... Q&A Python Bootcamp Python Training · ❮ Requests Module · Make a POST request to a web page, and return the response text: import requests url = 'https://www.w3schools.com/python/demopage.php' ...
Discussions

Post and Pre Requests in Python
How do you do post and pre requests in Python? I think in Postman, Insomnia - the only language supported is Javascript. And there should be support… More on reddit.com
🌐 r/learnpython
10
7
February 24, 2026
Python request (post)
Is using requests post method the correct way to fill in a search box on a website? I have been reading the docs and they all seem to suggest using the requests get method adding the search query to the url. The problem I have is the website uses a search box which I need to put text in (I think). More on discuss.python.org
🌐 discuss.python.org
4
0
November 28, 2022
Post request not work
Hi all, I’m working with request library using post: if I run: url = "\"https://server.com/admin/api/api?format=json2&X-API-KEY=internal_batch\"" headers = "\"Content-Type: application/x-www-form-urlencoded\"" data = "\"payload\"=" data += "\'[{\"timestamp\": " + str(1624872100) + ", \"lat\": ... More on discuss.python.org
🌐 discuss.python.org
0
0
June 29, 2021
[Python] How to receive a POST request and process it?
Keep in mind that any HTTP request path (the thing starting with / and leading to server.py) is just a parameter. There's no way of knowing what the webserver intends to do with your request. What is the server running? More on reddit.com
🌐 r/learnprogramming
9
1
February 3, 2016
People also ask

Does the Python requests library support asynchronous POST requests?

Unfortunately, the requests library does not support asynchronous requests. However, the httpx library is an alternative that provides async capabilities, making it suitable for applications requiring concurrency. See our guide to Python httpx for details.

🌐
scrapfly.io
scrapfly.io › blog › posts › how-to-python-requests-post
Guide to Python requests POST method - Scrapfly Blog
How can I include custom headers in using Python requests?

Pass headers as a dictionary using the headers parameter. Note that requests automatically generates some headers like User-Agent, Content-Length and Content-Type, so be cautious when overriding them.

🌐
scrapfly.io
scrapfly.io › blog › posts › how-to-python-requests-post
Guide to Python requests POST method - Scrapfly Blog
What is the difference between data and json parameters in Python requests?

data is for form-encoded (default) or raw data (when Content-Type header is overriden). While json is specifically for JSON format data and automatically sets Content-Type to application/json.

🌐
scrapfly.io
scrapfly.io › blog › posts › how-to-python-requests-post
Guide to Python requests POST method - Scrapfly Blog
🌐
Scrapfly
scrapfly.io › blog › posts › how-to-python-requests-post
Guide to Python requests POST method - Scrapfly Blog
1 month ago - The requests.post() function is your primary tool for sending POST requests in Python. It allows for customizable and straightforward data sending by specifying the URL, headers, and the data itself.
Find elsewhere
🌐
Reddit
reddit.com › r/learnpython › post and pre requests in python
r/learnpython on Reddit: Post and Pre Requests in Python
February 24, 2026 - Those tools expose scripting hooks because they’re orchestrating requests from a GUI. In Python itself, there’s no separate concept of “pre” or “post” scripts - it’s just normal code before and after a request.
🌐
PyPI
pypi.org › project › requests
requests · PyPI
2 days ago - There’s no need to manually add query strings to your URLs, or to form-encode your PUT & POST data — but nowadays, just use the json method! Requests is one of the most downloaded Python packages today, pulling in around 300M downloads / week — according to GitHub, Requests is currently ...
      » pip install requests
    
Published   May 11, 2026
Version   2.34.0
🌐
Oxylabs
oxylabs.io › blog › how-to-send-post-python-request
How to Send a POST with Python Requests?
To send a POST request using the Python requests library, you need to use the requests.post() method.
🌐
Mimo
mimo.org › glossary › python › requests-library
Python requests Library: How to Make HTTP Requests with Python
While GET retrieves data, the Python request POST sends data to a server to create or update resources. Typically, POST submits information, such as form data, user input, or API payloads, as part of the request's body.
🌐
Python.org
discuss.python.org › python help
Python request (post) - Python Help - Discussions on Python.org
November 28, 2022 - Is using requests post method the correct way to fill in a search box on a website? I have been reading the docs and they all seem to suggest using the requests get method adding the search query to the url. The proble…
🌐
Python.org
discuss.python.org › python help
Post request not work - Python Help - Discussions on Python.org
June 29, 2021 - Hi all, I’m working with request library using post: if I run: url = "\"https://server.com/admin/api/api?format=json2&X-API-KEY=internal_batch\"" headers = "\"Content-Type: application/x-www-form-urlencoded\"" data = "\"payload\"=" data += "\'[{\"timestamp\": " + str(1624872100) + ", \"lat\": " + str(0) + ", \"lon\": " + str(0) + "}]\'" command = "curl -X POST -H " + headers + " -d " + data + " " + url r = os.system(command) it works. but if I run: API_PROD_URL = "https://server.com/admin"...
🌐
GeeksforGeeks
geeksforgeeks.org › python › post-method-python-requests
POST method - Python requests - GeeksforGeeks
July 12, 2025 - It is often used when uploading a file or when submitting a completed web form. Python's requests module provides in-built method called post() for making a POST request to a specified URI.
🌐
ScrapingBee
scrapingbee.com › blog › how-to-send-post-python-requests
How to send a POST with Python Requests? | ScrapingBee
January 11, 2026 - Using the requests library keeps things clean and human-friendly. No browser automation, no Selenium gymnastics, no pretending to click buttons. You just send a POST request in Python, wait for the response, and continue on.
🌐
ScrapeOps
scrapeops.io › home › python web scraping playbook › python requests post requests
Python Requests - How to Send POST Requests | ScrapeOps
April 12, 2023 - To send POST requests with Python Requests use the requests.post() method and add the POST body and Content-Type using the body and headers parameters.
🌐
Real Python
realpython.com › python-requests
Python's Requests Library (Guide) – Real Python
July 23, 2025 - To add headers to requests, pass a dictionary of headers to the headers parameter in your request. To send POST data, use the data parameter for form-encoded data or the json parameter for JSON data.
🌐
ScrapingDog
scrapingdog.com › blog › send-post-python-requests
How To Send A Post Requests in Python?
October 2, 2024 - Learn how to send POST requests using Python’s Requests library. Includes step-by-step examples and code snippets.
🌐
Tutorialspoint
tutorialspoint.com › python › python_requests_module.htm
Python - Requests Methods
The 'requests' module in Python simplifies HTTP requests by offering a user-friendly interface for sending and handling responses. It supports various HTTP methods such as GET, POST, PUT, DELETE, HEAD and OPTIONS, where each accessible through corresponding functions.
🌐
ReqBin
reqbin.com › code › python › m2g4va4a › python-requests-post-json-example
How do I post JSON using the Python Requests Library?
To post a JSON to the server using Python Requests Library, call the requests.post() method and pass the target URL as the first parameter and the JSON data with the json= parameter.
🌐
AnyIP
anyip.io › blog › python-requests-post
How to make a POST with the Python Requests module?
April 2, 2025 - The POST HTTP method is used when you want to send data inside the request's body. The post(…) function sends an HTTP request with the POST method.