MIME Types
ActiveMIME (Multipurpose Internet Mail Extensions) types, also called media types or content types, identify the format of a file or data stream. Defined by RFC 2045-2046 and maintained by IANA, MIME types are used in HTTP Content-Type and Accept headers, email attachments, file system associations, and API contracts. Every web developer encounters MIME types daily when building APIs, handling file uploads, or configuring web servers.
In one line
MIME types (RFC 2046 + IANA registry) identify the format of data in HTTP, email, and APIs. Format: type/subtype;parameter. Top-level types: application, text, image, audio, video, multipart, font. The Content-Type header sends the MIME type; Accept requests it. Common: application/json, text/html, multipart/form-data, application/octet-stream. IANA maintains the official registry at iana.org/assignments/media-types.
Quick Reference
| Field | Size | Description |
|---|---|---|
| Syntax | type/subtype;param=val | type: top-level category (application, text, image, audio, video, multipart, font). subtype: specific format. Optional parameters after semicolon: charset, boundary, q. |
| Top-level types | 8 registered | application (binary/structured data), text (human-readable), image (visual), audio (sound), video (moving image), multipart (multiple body parts), font (typeface), message (email encapsulation). |
| Content-Type | HTTP request/response | Sent by server in response to declare format. Sent by client in POST/PUT to declare body format. RFC 9110 §8.3. Without Content-Type, browsers sniff the type (security risk – always set it). |
| Accept | HTTP request header | Client declares acceptable response formats. Accept: application/json, text/html;q=0.9. q-value (0–1) sets preference weight. * / * accepts anything. |
| charset | text/* parameter | Character encoding for text types. Content-Type: text/html;charset=utf-8. Default is ISO-8859-1 for text/* (but UTF-8 should always be specified explicitly). |
| boundary | multipart/* parameter | Required for multipart types. Unique string that separates body parts. Content-Type: multipart/form-data;boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW. |
| +suffix | structured syntax | RFC 6838 suffix convention: +json means parseable as JSON (e.g., application/ld+json), +xml parseable as XML, +zip is ZIP-compressed. Allows generic parsers to handle structured types. |
| x- prefix | Deprecated | Experimental types historically used x- prefix (application/x-www-form-urlencoded). RFC 6648 deprecated x- for new registrations. Existing x- types remain (x-www-form-urlencoded is still standard). |
Key Characteristics
Content negotiation
HTTP clients send Accept headers listing acceptable types; servers respond with Content-Type matching what was produced. If no match, server returns 406 Not Acceptable. Most REST APIs ignore Accept and always return application/json.
Never skip Content-Type
Browsers that receive a response without Content-Type will sniff the content to guess the type. This enables MIME sniffing attacks. Always set Content-Type explicitly. Use X-Content-Type-Options: nosniff to disable sniffing in browsers.
File upload validation
Never trust a file's MIME type from the client. The Content-Type in a multipart upload is client-controlled and can be faked. Validate file content (magic bytes) on the server after upload.
API content type
REST APIs: always send Content-Type: application/json with JSON bodies. Accept: application/json in requests. application/x-www-form-urlencoded for HTML form submissions. multipart/form-data for file uploads.
Message Format
# Content-Type in HTTP responses
GET /api/users/1 HTTP/1.1
Accept: application/json, text/html;q=0.9
HTTP/1.1 200 OK
Content-Type: application/json;charset=utf-8
{ "id": 1, "name": "Alice" }
# Content-Type in HTTP requests (POST with JSON body)
POST /api/users HTTP/1.1
Content-Type: application/json
{ "name": "Bob", "email": "[email protected]" }
# File upload (multipart/form-data)
POST /upload HTTP/1.1
Content-Type: multipart/form-data;boundary=----Boundary1234
------Boundary1234
Content-Disposition: form-data; name="file"; filename="photo.jpg"
Content-Type: image/jpeg
[binary JPEG data]
------Boundary1234--# HTML form submission
POST /login HTTP/1.1
Content-Type: application/x-www-form-urlencoded
username=alice&password=secret123
# Server-Sent Events stream
GET /events HTTP/1.1
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
data: {"type":"update","id":1}
# JSON with structured syntax suffix
GET /graph HTTP/1.1
Accept: application/ld+json
HTTP/1.1 200 OK
Content-Type: application/ld+json
{"@context":"https://schema.org","@type":"Person","name":"Alice"}
# Security: prevent MIME sniffing
HTTP/1.1 200 OK
Content-Type: text/plain
X-Content-Type-Options: nosniff