Почему тело HTTP-запроса POST должно быть заключено в JSON?

Я столкнулся с этой проблемой, когда играл с внешним API. Я отправлял данные моего тела в виде словаря прямо в запрос и получал 400 ошибок:

data = {
  "someParamRange": {
    "to": 1000, 
    "from": 100
  }, 
  "anotherParamRange": {
    "to": True, 
    "from": False
  }
}

Когда я добавил обертку json.dumps, она работает:

data = json.dumps({
  "someParamRange": {
    "to": 1000, 
    "from": 100
  }, 
  "anotherParamRange": {
    "to": True, 
    "from": False
  }
})

Я не совсем понимаю, почему это необходимо, так как словари и объекты JSON синтаксически идентичны. Может кто-нибудь помочь мне понять, что здесь происходит за кулисами?

Для полноты вот мои заголовки:

headers = {'API-KEY': 'blerg', 'Accept-Encoding': 'UTF-8', 'Content-Type': 'application/json', 'Accept': '*/*', 'username': 'user', 'password': 'pwd'}

РЕДАКТИРОВАТЬ:

Я не упоминал об этом раньше, но теперь я чувствую, что это может быть актуально. Я использую библиотеку Python Requests, и другой пост, похоже, предполагает, что вам никогда не придется кодировать параметры объекта запроса:https://stackoverflow.com/a/14804320/1012040

«Независимо от того, GET / POST вам никогда не придется кодировать параметры снова, он просто принимает словарь в качестве аргумента и хорошо идти».

Кажется, сериализация не должна быть необходимой?

Мой объект запроса:

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

Ответы на вопрос(2)

Ваш ответ на вопрос