Postman’s "request body" isn’t just a place to dump data; it’s a declaration of how that data should be interpreted by the server, and most people only use a fraction of its power.

Let’s see it in action. Imagine you’re building an API for a simple to-do list. You want to create a new task.

First, the most common way: JSON.

{
  "title": "Buy groceries",
  "completed": false
}

In Postman, you’d select "raw" in the body tab, and then "JSON" from the dropdown next to it.

// Example request in Postman's console (to see what's sent)
pm.sendRequest({
    url: 'https://your-api.com/todos',
    method: 'POST',
    header: {
        'Content-Type': 'application/json'
    },
    body: {
        mode: 'raw',
        raw: JSON.stringify({
            title: 'Buy groceries',
            completed: false
        })
    }
}, function (err, response) {
    console.log(err);
    console.log(response.json());
});

This tells the server, "Here’s a JavaScript Object Notation structure." The Content-Type: application/json header is crucial; it’s the server’s cue.

Now, what if your API expects form-encoded data, like a traditional HTML form submission?

title=Buy+groceries&completed=false

In Postman, you’d select "form-urlencoded" from the body type dropdown. You then enter key-value pairs. Postman automatically formats this and sets the Content-Type header to application/x-www-form-urlencoded.

// Example request in Postman's console
pm.sendRequest({
    url: 'https://your-api.com/todos',
    method: 'POST',
    header: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: {
        mode: 'urlencoded',
        urlencoded: [
            { key: 'title', value: 'Buy groceries' },
            { key: 'completed', value: 'false' }
        ]
    }
}, function (err, response) {
    console.log(err);
    console.log(response.json());
});

This is handy for older APIs or when mimicking browser form submissions. The server receives a simple string and parses it based on the & and = delimiters.

There’s also "form-data," which is different from "form-urlencoded." This is what you use for file uploads or when you need to send a mix of text fields and files.

Imagine uploading a picture for your to-do item.

In Postman, you’d select "form-data." For a text field like "title," you’d enter title as the key and Buy groceries as the value. For a file, you’d enter image as the key, select "File" as the type, and then choose your file. Postman handles the multipart/form-data encoding and sets the correct header.

// Example request in Postman's console
pm.sendRequest({
    url: 'https://your-api.com/todos',
    method: 'POST',
    header: {
        'Content-Type': 'multipart/form-data' // Postman sets this
    },
    body: {
        mode: 'formdata',
        formdata: [
            { key: 'title', value: 'Buy groceries', type: 'text' },
            { key: 'image', src: '/path/to/your/image.jpg', type: 'file' }
        ]
    }
}, function (err, response) {
    console.log(err);
    console.log(response.json());
});

This format is more complex, using boundaries to separate different parts of the request, each with its own Content-Disposition header. It’s essential for binary data.

Beyond these, there’s "binary" for sending raw files directly (often used for single file uploads where the Content-Type is set manually) and "none" if your request doesn’t require a body at all (like a GET request).

The most surprising thing is how often developers struggle with Content-Type headers when dealing with raw bodies. If you send JSON data but forget to set Content-Type: application/json, many servers will default to a generic text/plain or even application/octet-stream, leading to parsing errors on the server-side because they don’t know how to interpret the incoming stream of bytes. Postman tries to be helpful by setting it based on your selection, but it’s your responsibility to ensure it matches the server’s expectation.

The real power comes from understanding that Postman is just a client for crafting these HTTP requests. The "body" tab is where you define the payload and, critically, the Content-Type header that tells the server exactly how to deserialize that payload. If your server expects XML, you’d select "raw" and then "XML" from the dropdown, ensuring Content-Type: application/xml is sent.

Once you’ve mastered these body types, you’ll naturally start looking into how to handle different response formats and how to use variables to dynamically build these request bodies for more complex workflows.

Want structured learning?

Take the full Postman course →