HTTP Content-Type Header: Complete Guide (2026)
Everything developers need to know about Content-Type headers
Start Building with Hypereal
Access Kling, Flux, Sora, Veo & more through a single API. Free credits to start, scale to millions.
No credit card required • 100k+ developers • Enterprise ready
HTTP Content-Type Header: Complete Guide (2026)
The Content-Type header is one of the most important HTTP headers. It tells the server (or client) what type of data is in the request or response body, so it knows how to parse and handle it. Getting Content-Type wrong causes some of the most common API errors: 415 Unsupported Media Type, malformed JSON, broken file uploads, and garbled text.
This guide covers everything you need to know about Content-Type, from MIME types to practical examples in every major language and framework.
What Is the Content-Type Header?
The Content-Type header is an HTTP entity header that indicates the media type (also called MIME type) of the resource or the data in the body of a request or response. It follows this format:
Content-Type: type/subtype; parameter=value
For example:
Content-Type: application/json; charset=utf-8
Content-Type: text/html; charset=utf-8
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
The Three Parts
| Part | Description | Example |
|---|---|---|
| Type | The general category | application, text, image, audio, video, multipart |
| Subtype | The specific format | json, html, png, mp4, form-data |
| Parameters | Optional metadata | charset=utf-8, boundary=xxx |
Common Content-Type Values
Here is a reference table of the most commonly used Content-Type values in web development and APIs:
Text Types
| Content-Type | Used For |
|---|---|
text/plain |
Plain text with no formatting |
text/html |
HTML documents |
text/css |
CSS stylesheets |
text/javascript |
JavaScript files |
text/csv |
Comma-separated values |
text/xml |
XML documents (prefer application/xml) |
Application Types
| Content-Type | Used For |
|---|---|
application/json |
JSON data (most common for APIs) |
application/xml |
XML data |
application/x-www-form-urlencoded |
HTML form data (default) |
application/octet-stream |
Binary data (generic) |
application/pdf |
PDF documents |
application/zip |
ZIP archives |
application/gzip |
Gzip compressed data |
application/graphql+json |
GraphQL requests |
Multipart Types
| Content-Type | Used For |
|---|---|
multipart/form-data |
File uploads and form data with files |
multipart/mixed |
Mixed content types in a single message |
multipart/alternative |
Same content in different formats (email) |
Image Types
| Content-Type | Used For |
|---|---|
image/png |
PNG images |
image/jpeg |
JPEG images |
image/gif |
GIF images |
image/webp |
WebP images |
image/svg+xml |
SVG vector images |
image/avif |
AVIF images |
Audio and Video Types
| Content-Type | Used For |
|---|---|
audio/mpeg |
MP3 audio |
audio/wav |
WAV audio |
audio/ogg |
OGG audio |
video/mp4 |
MP4 video |
video/webm |
WebM video |
When to Use Each Content-Type
application/json
The most common Content-Type for REST APIs. Use it whenever you send or receive structured data.
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "John", "email": "john@example.com"}'
application/x-www-form-urlencoded
The default Content-Type for HTML <form> submissions. Data is encoded as key-value pairs separated by &.
curl -X POST https://api.example.com/login \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=john&password=secret123"
The data looks like this in the request body:
username=john&password=secret123
Special characters are percent-encoded (e.g., spaces become + or %20).
multipart/form-data
Required for file uploads. Each field is sent as a separate part with its own Content-Type.
curl -X POST https://api.example.com/upload \
-H "Content-Type: multipart/form-data" \
-F "file=@photo.jpg" \
-F "description=My vacation photo"
Setting Content-Type in Different Languages
JavaScript (Fetch API)
// JSON request
const response = await fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: 'John', email: 'john@example.com' }),
});
// Form data (Content-Type is set automatically)
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('name', 'John');
const response = await fetch('https://api.example.com/upload', {
method: 'POST',
// Do NOT set Content-Type manually for FormData
// The browser sets it with the correct boundary
body: formData,
});
Python (Requests)
import requests
# JSON request (Content-Type is set automatically with json=)
response = requests.post(
'https://api.example.com/data',
json={'name': 'John', 'email': 'john@example.com'}
)
# Form-urlencoded (set automatically with data=)
response = requests.post(
'https://api.example.com/login',
data={'username': 'john', 'password': 'secret123'}
)
# File upload (Content-Type set automatically with files=)
with open('photo.jpg', 'rb') as f:
response = requests.post(
'https://api.example.com/upload',
files={'file': ('photo.jpg', f, 'image/jpeg')},
data={'description': 'My vacation photo'}
)
# Explicit Content-Type
response = requests.post(
'https://api.example.com/data',
headers={'Content-Type': 'application/xml'},
data='<user><name>John</name></user>'
)
Go
package main
import (
"bytes"
"encoding/json"
"net/http"
)
func main() {
// JSON request
data := map[string]string{"name": "John", "email": "john@example.com"}
jsonData, _ := json.Marshal(data)
req, _ := http.NewRequest("POST", "https://api.example.com/data",
bytes.NewBuffer(jsonData))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
}
cURL
# JSON
curl -X POST https://api.example.com/data \
-H "Content-Type: application/json" \
-d '{"name": "John"}'
# Form data
curl -X POST https://api.example.com/login \
-d "username=john&password=secret"
# File upload
curl -X POST https://api.example.com/upload \
-F "file=@photo.jpg" \
-F "description=My photo"
# Binary data
curl -X POST https://api.example.com/binary \
-H "Content-Type: application/octet-stream" \
--data-binary @file.bin
Content-Type in API Responses
Servers must also set the correct Content-Type in responses so clients know how to parse the data.
Express.js
app.get('/api/users', (req, res) => {
// res.json() sets Content-Type: application/json automatically
res.json({ users: [] });
});
app.get('/report.pdf', (req, res) => {
res.setHeader('Content-Type', 'application/pdf');
res.sendFile('/path/to/report.pdf');
});
app.get('/page', (req, res) => {
// res.send() with a string sets Content-Type: text/html
res.send('<h1>Hello</h1>');
});
FastAPI (Python)
from fastapi import FastAPI
from fastapi.responses import JSONResponse, HTMLResponse, StreamingResponse
app = FastAPI()
@app.get("/api/users")
async def get_users():
# Returns application/json by default
return {"users": []}
@app.get("/page", response_class=HTMLResponse)
async def get_page():
return "<h1>Hello</h1>"
@app.get("/download")
async def download_file():
return StreamingResponse(
open("file.pdf", "rb"),
media_type="application/pdf"
)
The charset Parameter
The charset parameter specifies the character encoding of text content. UTF-8 is the standard and should always be used unless you have a specific reason not to:
Content-Type: text/html; charset=utf-8
Content-Type: application/json; charset=utf-8
Note: The JSON specification (RFC 8259) states that JSON must be encoded in UTF-8. Technically, the charset parameter is unnecessary for application/json, but many APIs include it for clarity.
Content-Type vs. Accept Header
These two headers are often confused:
| Header | Purpose | Used In | Direction |
|---|---|---|---|
Content-Type |
Describes the body format | Requests and Responses | "This is what I'm sending" |
Accept |
Requests a specific format | Requests only | "This is what I want back" |
# "I'm sending JSON, and I want JSON back"
curl -X POST https://api.example.com/data \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name": "John"}'
Common Errors and How to Fix Them
415 Unsupported Media Type
The server does not accept the Content-Type you sent.
# Wrong: sending form data to a JSON-only endpoint
curl -X POST https://api.example.com/data \
-d "name=John"
# Fix: send JSON instead
curl -X POST https://api.example.com/data \
-H "Content-Type: application/json" \
-d '{"name": "John"}'
400 Bad Request (Malformed JSON)
Content-Type says JSON, but the body is not valid JSON.
# Wrong: not valid JSON
curl -X POST https://api.example.com/data \
-H "Content-Type: application/json" \
-d "name=John"
# Fix: use proper JSON syntax
curl -X POST https://api.example.com/data \
-H "Content-Type: application/json" \
-d '{"name": "John"}'
File Upload Fails with FormData
Do not manually set Content-Type when using FormData in JavaScript. The browser needs to set it with the correct boundary string.
// Wrong
const formData = new FormData();
formData.append('file', file);
fetch('/upload', {
method: 'POST',
headers: { 'Content-Type': 'multipart/form-data' }, // DO NOT DO THIS
body: formData,
});
// Correct
fetch('/upload', {
method: 'POST',
// Let the browser set Content-Type with boundary
body: formData,
});
Content Negotiation
Some APIs support multiple response formats. The client uses the Accept header to request a specific format, and the server uses Content-Type in the response to confirm what it sent:
# Request XML response
curl -H "Accept: application/xml" https://api.example.com/users
# Request JSON response
curl -H "Accept: application/json" https://api.example.com/users
Wrapping Up
The Content-Type header is fundamental to how HTTP communication works. Setting it correctly ensures that servers and clients parse data properly, file uploads work, and APIs return the right format. Most modern frameworks handle Content-Type automatically for common cases (JSON, form data), but understanding how it works helps you debug the inevitable edge cases.
If you are building applications that involve AI-generated media -- images, videos, audio, or talking avatars -- check out Hypereal AI for a unified API that returns media with the correct Content-Type headers and handles all the complexity for you.
Try Hypereal AI free -- 35 credits, no credit card required.
Related Articles
Start Building Today
Get 35 free credits on signup. No credit card required. Generate your first image in under 5 minutes.
