Loading learning content...
When you click a link that downloads a PDF, your browser doesn't peek inside the file to figure out what it is. When your email client displays an inline image rather than downloading it, it doesn't analyze pixel patterns to recognize an image. When an API responds with JSON and your code parses it correctly, the parsing library doesn't guess the format.
In every case, the answer is the same: the Content-Type header told the software exactly what to expect.
Content types, formally called Internet Media Types (and colloquially known as MIME types), form the universal classification system that enables software worldwide to correctly interpret the data it receives. This system is elegantly simple yet powerful enough to classify every type of digital content humanity has ever created—and extensible enough to classify types that don't yet exist.
This page provides a complete exploration of content types: their structure, the seven discrete type families, the registration process, parameters, and the practical considerations every engineer must understand.
By the end of this page, you will understand the two-level type/subtype hierarchy, the semantics of each discrete type category (text, image, audio, video, application, message) and composite type (multipart), the IANA registration system, how parameters extend type definitions, content type negotiation, and common pitfalls that cause real-world bugs.
Every content type follows a precise syntactic structure defined in RFC 6838. Understanding this structure is essential for correctly parsing, generating, and working with media types.
The Fundamental Format
A media type consists of a type, a subtype, and optional parameters, structured as:
type "/" subtype *(";" parameter)
Where:
text, image, application)plain, jpeg, json)The type and subtype are case-insensitive by specification (though lowercase is conventional), while parameter values may be case-sensitive depending on the specific parameter.
12345678910111213141516171819202122232425
# Basic format: type/subtypetext/plainimage/pngapplication/json # With single parametertext/plain; charset=utf-8application/json; charset=utf-8 # With multiple parameterstext/html; charset=utf-8; format=flowedmultipart/mixed; boundary="----=_Part_123_456.789" # With quoted parameter values (required if containing special characters)application/octet-stream; name="my file (1).pdf"multipart/form-data; boundary="----WebKitFormBoundary7MA4YWxkTrZu0gW" # With vendor prefixapplication/vnd.ms-excelapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet # With suffix indicating underlying structureapplication/calendar+xmlimage/svg+xmlapplication/ld+jsonThe Subtype Naming Convention
Subtypes follow specific naming conventions that convey important information:
Standard subtypes are simple names registered with IANA:
text/plain — Unformatted textimage/jpeg — JPEG image formataudio/mpeg — MPEG audio (e.g., MP3)Vendor subtypes use the vnd. prefix for proprietary or vendor-specific formats:
application/vnd.ms-powerpoint — Microsoft PowerPointapplication/vnd.oasis.opendocument.text — OpenDocument textimage/vnd.adobe.photoshop — Adobe Photoshop (PSD)Personal/vanity subtypes use the prs. prefix (rarely used in practice):
application/prs.example — Personal experimental formatUnregistered/experimental subtypes historically used the x- prefix:
application/x-tar — Tar archive (now deprecated convention)application/x-www-form-urlencoded — HTML form data (grandfather exception)The +suffix in subtypes (e.g., application/calendar+xml, application/ld+json) indicates the underlying syntax or encoding while the base subtype indicates semantic meaning. A client that doesn't understand 'calendar' might still parse the response as generic XML. This enables graceful degradation—unknown formats can still be partially processed if their structural suffix is recognized.
Parameters and Their Syntax
Parameters extend media types with additional metadata. Each parameter is a name=value pair:
media-type = type "/" subtype *(";" parameter)
parameter = attribute "=" value
value = token / quoted-string
Key rules for parameter values:
\")Common parameters by type:
| Parameter | Used With | Purpose | Example |
|---|---|---|---|
| charset | text/* | Character encoding | charset=utf-8 |
| boundary | multipart/* | Part delimiter | boundary="----abc123" |
| name | (any) | Suggested filename | name="report.pdf" |
| format | text/plain | Text format hints | format=flowed |
| profile | application/* | Schema reference | profile="http://..." |
The text type encompasses all content that is human-readable without special processing. While computers may need encoding information to correctly render text, the content is fundamentally character data meant for human consumption.
Core Semantics
Content with text/* types:
The charset Parameter
For text types, the charset parameter is critically important. It specifies the character encoding used to convert between bytes and characters:
text/plain; charset=utf-8
text/html; charset=iso-8859-1
text/csv; charset=utf-16le
Without an explicit charset, the default depends on protocol:
When charset is omitted, different systems make different assumptions. A file saved as UTF-8 on Linux might be interpreted as Windows-1252 on Windows. The result: characters like '—' (em-dash) become 'â€' (garbage). Always specify charset explicitly. Always use UTF-8 unless you have a compelling reason not to.
| Subtype | MIME Type | Description | Common Use |
|---|---|---|---|
| plain | text/plain | Unstructured plain text | README files, logs, simple messages |
| html | text/html | HTML markup language | Web pages, formatted email |
| css | text/css | Cascading Style Sheets | Styling web documents |
| javascript | text/javascript | JavaScript code | Client-side web scripting |
| csv | text/csv | Comma-separated values | Spreadsheet data exchange |
| xml | text/xml | XML documents (legacy) | Structured data (see application/xml) |
| calendar | text/calendar | iCalendar format | Calendar events (ics files) |
| markdown | text/markdown | Markdown markup | Documentation, README files |
Text vs Application: The Classification Dilemma
A persistent question is when to use text/* versus application/* for textual formats. The distinction is subtle:
Historically, this line was unclear. JavaScript was registered as application/javascript but widely served as text/javascript. XML exists as both text/xml and application/xml.
Modern best practice recommends:
text/html for HTMLtext/css for CSStext/javascript for JavaScript (standardized in RFC 9239)application/json for JSON (despite being human-readable)application/xml for XML (for consistency with processing model)The format=flowed Parameter
For text/plain, the format=flowed parameter (RFC 3676) provides soft-wrapping information:
text/plain; charset=utf-8; format=flowed
Flowed format indicates that soft line breaks may be recombined by recipients for display, while hard line breaks (no trailing space) must be preserved. This enables proper reformatting of plain text for different display widths.
1234567891011121314151617181920212223242526272829303132333435363738394041424344
# Plain text - simple human readable contentContent-Type: text/plain; charset=utf-8 This is a simple plain text message.No formatting, no structure, just characters. # HTML - formatted web contentContent-Type: text/html; charset=utf-8 <!DOCTYPE html><html><head><title>Example</title></head><body><h1>Hello World</h1></body></html> # CSS - stylesheetsContent-Type: text/css; charset=utf-8 body { font-family: 'Helvetica Neue', sans-serif; margin: 0; padding: 20px;} # CSV - tabular dataContent-Type: text/csv; charset=utf-8 Name,Age,Email"Tanaka, Yuki",28,yuki@example.jp"O'Brien, Sean",42,sean@example.ie"García, María",35,maria@example.es # Calendar data (iCalendar)Content-Type: text/calendar; charset=utf-8; method=REQUEST BEGIN:VCALENDARVERSION:2.0METHOD:REQUESTBEGIN:VEVENTDTSTART:20240120T090000ZDTEND:20240120T100000ZSUMMARY:Project Planning MeetingEND:VEVENTEND:VCALENDARThese three type families cover rich media content — visual images, sound recordings, and moving pictures. While browsers and media players handle the heavy lifting of decoding and rendering, understanding these types is essential for web developers, API designers, and anyone working with multimedia content.
Image Types
The image type encompasses all visual graphical content. Modern web development requires familiarity with several distinct formats, each with different compression characteristics, browser support, and use cases.
| MIME Type | Format | Compression | Use Case | Browser Support |
|---|---|---|---|---|
| image/jpeg | JPEG | Lossy | Photographs, complex images | Universal |
| image/png | PNG | Lossless | Screenshots, graphics with transparency | Universal |
| image/gif | GIF | Lossless, palette | Simple animations, legacy graphics | Universal |
| image/webp | WebP | Lossy or lossless | Modern web images, smaller than JPEG/PNG | Modern browsers |
| image/avif | AVIF | Lossy, highly efficient | Next-gen web images, best compression | Growing support |
| image/svg+xml | SVG | N/A (vector) | Icons, logos, scalable graphics | Universal |
| image/bmp | BMP | None (uncompressed) | Legacy Windows graphics | Universal |
| image/tiff | TIFF | Various | Professional photography, print | Limited (desktop) |
| image/heic | HEIC/HEIF | Lossy, efficient | Apple device photos | Limited (Safari, native apps) |
Content Negotiation for Images
Modern web servers can serve different image formats based on browser capabilities:
GET /logo HTTP/1.1
Accept: image/avif, image/webp, image/png, image/jpeg, */*
The server can then respond with the optimal format the client supports. This technique enables serving smaller AVIF or WebP files to modern browsers while falling back to JPEG/PNG for older ones.
Audio Types
The audio type covers sound content, from simple notification sounds to complex musical compositions. Audio encoding is a deep technical field, but developers need to understand the practical aspects of format support and streaming.
| MIME Type | Format | Notes |
|---|---|---|
| audio/mpeg | MP3 (MPEG Layer III) | Universal support, lossy compression, ubiquitous |
| audio/ogg | Ogg Vorbis/Opus | Open format, good quality, Opus excellent for voice |
| audio/wav | WAV (RIFF) | Uncompressed, large files, professional audio |
| audio/webm | WebM Audio | Web-focused, Vorbis or Opus codec |
| audio/aac | AAC (Advanced Audio Coding) | Apple ecosystem, better than MP3 at same bitrate |
| audio/flac | FLAC | Lossless compression, audiophile use |
| audio/midi | MIDI | Musical notation, not audio data, requires synthesizer |
Video Types
Video is the most complex media type, involving both visual frames and typically one or more audio tracks, subtitles, and metadata. Video formats often involve container formats (which hold multiple streams) and codecs (which encode/decode the streams).
| MIME Type | Container | Common Codecs | Notes |
|---|---|---|---|
| video/mp4 | MP4 (MPEG-4 Part 14) | H.264, H.265, AAC | Universal, most compatible |
| video/webm | WebM | VP8, VP9, AV1, Vorbis, Opus | Open format, web-focused |
| video/ogg | Ogg | Theora, Vorbis | Open format, declining use |
| video/quicktime | QuickTime (MOV) | Various | Apple ecosystem, production |
| video/x-msvideo | AVI | Various | Legacy Windows, unregistered |
| video/x-matroska | Matroska (MKV) | Various | Feature-rich container, unregistered |
A video MIME type identifies the container format, not necessarily the codec. An MP4 file might contain H.264 video (widely supported) or H.265/HEVC video (less supported). The codecs parameter can specify this: video/mp4; codecs="avc1.42E01E, mp4a.40.2". However, not all systems check this parameter.
12345678910111213141516171819202122
<!-- HTML5 video with codec specification for progressively enhanced playback --><video controls> <!-- Most efficient: AV1 in WebM container --> <source src="video.webm" type='video/webm; codecs="av01.0.05M.08"'> <!-- Fallback: VP9 in WebM container --> <source src="video-vp9.webm" type='video/webm; codecs="vp9, vorbis"'> <!-- Wide compatibility: H.264 in MP4 container --> <source src="video.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'> <!-- Ultimate fallback for ancient browsers --> <p>Your browser doesn't support HTML5 video.</p></video> <!-- HTML5 audio with progressive source selection --><audio controls> <source src="audio.opus" type="audio/ogg; codecs=opus"> <source src="audio.ogg" type="audio/ogg; codecs=vorbis"> <source src="audio.mp3" type="audio/mpeg"> <p>Your browser doesn't support HTML5 audio.</p></audio>The application type is the most diverse type family, serving as both a specific category and a catch-all for content that doesn't fit elsewhere. It encompasses machine-processable data, executable programs, compressed archives, office documents, and structured data formats.
Core Semantics
Content labeled application/* is:
The Universal Fallback: application/octet-stream
When a sender doesn't know (or won't reveal) the content type, application/octet-stream serves as the generic binary type:
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="mystery-file.bin"
Recipients typically offer to download such content rather than attempting to display or process it. Using octet-stream when you know the actual type is an anti-pattern—it prevents automatic handling.
| MIME Type | Format | Description |
|---|---|---|
| application/json | JSON | JavaScript Object Notation, ubiquitous data interchange |
| application/xml | XML | Extensible Markup Language, structured documents |
| application/pdf | Portable Document Format, Adobe's document format | |
| application/zip | ZIP | Compressed archive format |
| application/gzip | GZIP | GNU zip compression |
| application/octet-stream | (binary) | Arbitrary binary data, generic fallback |
| application/javascript | JavaScript | JavaScript code (deprecated, use text/javascript) |
| application/x-www-form-urlencoded | Form data | HTML form submission encoding |
| application/ld+json | JSON-LD | Linked Data in JSON format |
| application/wasm | WebAssembly | WebAssembly binary format |
Structured Data Formats
Modern APIs predominantly use two textual data formats:
JSON (application/json) has become the de facto standard for web APIs:
Content-Type: application/json; charset=utf-8
{"name": "Tanaka", "age": 28, "languages": ["Japanese", "English"]}
XML (application/xml) remains important for SOAP services, configuration, and enterprise systems:
Content-Type: application/xml; charset=utf-8
<?xml version="1.0" encoding="UTF-8"?>
<person><name>Tanaka</name><age>28</age></person>
Document Formats
Office productivity suites use vendor-prefixed MIME types:
| Format | MIME Type |
|---|---|
| Word (.docx) | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
| Word (.doc) | application/msword |
| Excel (.xlsx) | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
| Excel (.xls) | application/vnd.ms-excel |
| PowerPoint (.pptx) | application/vnd.openxmlformats-officedocument.presentationml.presentation |
| application/pdf | |
| OpenDocument Text (.odt) | application/vnd.oasis.opendocument.text |
| OpenDocument Spreadsheet (.ods) | application/vnd.oasis.opendocument.spreadsheet |
For archive formats: application/zip for ZIP, application/gzip for GZIP, application/x-tar for TAR (unregistered), and application/x-7z-compressed for 7-Zip (unregistered). The lack of registration for some formats reflects their origin before formal IANA procedures were established.
12345678910111213141516171819202122232425262728293031323334353637383940
# JSON API ResponseHTTP/1.1 200 OKContent-Type: application/json; charset=utf-8Content-Length: 127 { "status": "success", "data": { "user_id": 12345, "username": "tanaka_yuki", "created_at": "2024-01-15T10:30:00Z" }} # PDF Document DownloadHTTP/1.1 200 OKContent-Type: application/pdfContent-Disposition: attachment; filename="invoice-2024-001.pdf"Content-Length: 245789 %PDF-1.7[binary PDF data...] # Form Submission (URL-encoded)POST /api/login HTTP/1.1Content-Type: application/x-www-form-urlencodedContent-Length: 45 username=tanaka&password=secret123&remember=1 # File Upload (multipart/form-data uses boundary)POST /api/upload HTTP/1.1Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4 ------WebKitFormBoundary7MA4Content-Disposition: form-data; name="file"; filename="photo.jpg"Content-Type: image/jpeg [binary JPEG data...]------WebKitFormBoundary7MA4--The multipart type family is unique among MIME types—it's composite rather than discrete. While other types describe a single piece of content, multipart types contain multiple body parts, each with its own Content-Type.
The Boundary Mechanism
Multipart messages use a boundary string to delimit parts. This boundary:
boundary parameter-- to mark part boundaries-- suffix to mark the end of all partsContent-Type: multipart/mixed; boundary="----=_Part_123"
------=_Part_123
Content-Type: text/plain
This is the first part.
------=_Part_123
Content-Type: image/png
[binary PNG data...]
------=_Part_123--
| Subtype | Purpose | Common Usage |
|---|---|---|
| mixed | Unrelated parts in sequence | Email with attachments |
| alternative | Same content, different formats | HTML email with text fallback |
| related | Aggregated parts forming coherent whole | HTML with inline images |
| parallel | Parts to display simultaneously | Audio+video sync (rare) |
| digest | Collection of message/rfc822 parts | Email digests |
| form-data | HTML form with file uploads | HTTP file upload |
| byteranges | Partial content responses | HTTP range requests |
| signed | Content with cryptographic signature | S/MIME signed emails |
| encrypted | Encrypted content | S/MIME encrypted emails |
multipart/mixed — The General Container
The most common multipart type, used when parts are independent and meant to be processed sequentially. A typical email with attachments uses multipart/mixed:
Content-Type: multipart/mixed; boundary="MixedBoundary"
--MixedBoundary
Content-Type: text/plain
Please find the attached documents.
--MixedBoundary
Content-Type: application/pdf; name="report.pdf"
Content-Disposition: attachment; filename="report.pdf"
Content-Transfer-Encoding: base64
JVBERi0xLjcKJeLjz9MKN...
--MixedBoundary
Content-Type: image/png; name="chart.png"
Content-Disposition: attachment; filename="chart.png"
Content-Transfer-Encoding: base64
iVBORw0KGgoAAAANS...
--MixedBoundary--
multipart/alternative — Format Selection
Used when the same semantic content is provided in multiple formats. Recipients choose the best format they can display. Parts are ordered from simplest to most feature-rich:
Content-Type: multipart/alternative; boundary="AltBoundary"
--AltBoundary
Content-Type: text/plain; charset=utf-8
Welcome to our newsletter!
--AltBoundary
Content-Type: text/html; charset=utf-8
<html><body><h1>Welcome to our newsletter!</h1></body></html>
--AltBoundary--
Email clients display the HTML version if supported, falling back to plain text if not.
Multipart types can be nested for complex structures. An HTML email with inline images and separate attachments might use multipart/mixed containing multipart/related (for HTML+images) and attachment parts. Parsing must be recursive to handle arbitrary nesting depth.
123456789101112131415161718192021222324252627282930313233343536373839404142434445
Content-Type: multipart/mixed; boundary="outer"MIME-Version: 1.0Subject: Newsletter with inline images and attachment --outerContent-Type: multipart/alternative; boundary="alternative" --alternativeContent-Type: text/plain; charset=utf-8 See the attached images and chart! --alternativeContent-Type: multipart/related; boundary="related" --relatedContent-Type: text/html; charset=utf-8 <html><body> <h1>Monthly Report</h1> <p>Here's our progress:</p> <img src="cid:chart@example.com" alt="Progress Chart"></body></html> --relatedContent-Type: image/pngContent-ID: <chart@example.com>Content-Transfer-Encoding: base64 iVBORw0KGgoAAAANSUhEUgAA... --related-- --alternative-- --outerContent-Type: application/pdfContent-Disposition: attachment; filename="full-report.pdf"Content-Transfer-Encoding: base64 JVBERi0xLjcKJeLjz9MNCjcg... --outer--multipart/form-data — Web Form Uploads
This type enables web forms to submit both text fields and binary files:
POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary="----FormBoundary"
Content-Length: 10234
------FormBoundary
Content-Disposition: form-data; name="username"
tanaka_yuki
------FormBoundary
Content-Disposition: form-data; name="avatar"; filename="photo.jpg"
Content-Type: image/jpeg
[binary JPEG data...]
------FormBoundary
Content-Disposition: form-data; name="bio"
Software engineer from Tokyo.
------FormBoundary--
Each form field becomes a separate part, with file fields including the filename and Content-Type.
The message type family handles encapsulated messages—complete messages wrapped within other messages. This enables forwarding, digests, partial message delivery, and references to external content.
message/rfc822 — Complete Email Messages
When forwarding an email "as attachment" rather than inline, the original message is wrapped with:
Content-Type: message/rfc822
Content-Disposition: attachment; filename="Forwarded Message.eml"
From: original-sender@example.com
To: original-recipient@example.com
Subject: Original Subject
Date: Mon, 15 Jan 2024 10:30:00 +0900
MIME-Version: 1.0
Content-Type: text/plain
This was the original message body.
The entire original message, including all its headers and body, becomes the content of the message/rfc822 part. Recipients can save this part as a .eml file and open it in their email client.
| Subtype | Purpose | Use Case |
|---|---|---|
| rfc822 | Complete RFC 5322 message | Forwarded emails, email attachments |
| partial | Fragment of large message | Splitting oversized messages |
| external-body | Reference to external content | Deferred retrieval, large attachments |
| delivery-status | Delivery status notification | Bounce messages, DSN reports |
| disposition-notification | Read receipt information | MDN reports |
| http | HTTP request or response | Encapsulated HTTP (rare) |
message/partial — Large Message Splitting
Historically significant for bypassing message size limits, message/partial divides large messages into smaller fragments:
Content-Type: message/partial; id="unique-msg-id"; number=1; total=3
[First portion of the large message...]
Recipient systems reassemble the fragments using the id and number parameters. While rarely used today (modern systems handle large messages directly), understanding this mechanism provides insight into MIME's design for constrained environments.
message/external-body — Deferred Retrieval
This type tells recipients where to fetch content rather than including it directly:
Content-Type: message/external-body; access-type=URL;
URL="https://example.com/large-attachment.zip"
Content-Type: application/zip
Content-Description: Large archive (150 MB)
The body contains headers describing what will be retrieved, while the actual content is fetched separately. This enables sending references to large files without transmitting them through email systems.
Bounce messages and delivery failure notifications use message/delivery-status to provide machine-readable delivery information. When your email bounces, the structured error information in the DSN is carried in this format, enabling automated processing of delivery failures.
The Internet Assigned Numbers Authority (IANA) maintains the official registry of media types at iana.org/assignments/media-types. This centralized registry ensures global consistency and prevents conflicting type definitions.
Registration Process
New media types follow a structured registration process defined in RFC 6838:
Standards Tree Types (no prefix): Require IETF standards track publication
application/json (RFC 8259)Vendor Tree Types (vnd. prefix): Require registration application to IANA
application/vnd.ms-excelPersonal/Vanity Tree (prs. prefix): Self-registered, no approval needed
application/prs.my-custom-formatUnregistered Types (x- prefix): Deprecated but still widely used
application/x-tarRFC 6648 deprecated the x- prefix in 2012 because experimental types often became permanent, but the x- prefix persisted, creating ambiguity about their status. Some x- types like application/x-www-form-urlencoded are so widely used they can never be changed. New types should be registered formally rather than using x- prefixes.
What's in a Registration
A complete IANA media type registration includes:
Discovering Unknown Types
When encountering an unknown media type:
+xml, +json, or +cbor indicate underlying formatvnd. prefix are documented by vendorsimage/*) can use generic handling1234567891011121314151617181920212223242526
# The +suffix convention for structured types # XML-based formatsapplication/atom+xml # Atom feedsapplication/rss+xml # RSS feeds (older)application/xhtml+xml # XHTML documentsapplication/svg+xml # SVG imagesapplication/calendar+xml # XML calendar data # JSON-based formatsapplication/ld+json # JSON-LD (Linked Data)application/hal+json # Hypertext Application Languageapplication/vnd.api+json # JSON:API specificationapplication/geo+json # GeoJSON geographic dataapplication/jwt # JWT (no suffix, but JSON-based) # Binary structured formatsapplication/cbor # Concise Binary Object Representationapplication/protobuf # Protocol Buffersapplication/msgpack # MessagePack # A client that doesn't understand "calendar+xml" can:# 1. Recognize it as XML from the +xml suffix# 2. Parse it as generic XML# 3. Display or process the XML content# 4. Even if calendar semantics are lost, the data is preservedContent negotiation is the mechanism by which clients and servers agree on the best content representation to exchange. MIME types are central to this process, appearing in HTTP's Accept and Content-Type headers.
Client-Driven Negotiation (Accept Headers)
Clients express their preferences using the Accept header:
GET /api/users/123 HTTP/1.1
Host: api.example.com
Accept: application/json, application/xml;q=0.9, text/html;q=0.5, */*;q=0.1
The quality factor (q) indicates preference strength (0.0 to 1.0):
application/json — q=1.0 (default, highest priority)application/xml;q=0.9 — Second choicetext/html;q=0.5 — Acceptable but not preferred*/*;q=0.1 — Anything else as last resortServers select the highest-preference type they support and respond accordingly.
| Request Header | Response Header | Purpose |
|---|---|---|
| Accept | Content-Type | Content format negotiation |
| Accept-Charset | (implicit in Content-Type charset) | Character encoding negotiation |
| Accept-Encoding | Content-Encoding | Compression negotiation |
| Accept-Language | Content-Language | Language negotiation |
Server-Driven Negotiation
When servers have multiple representations available, they can indicate this with the Vary header:
HTTP/1.1 200 OK
Content-Type: application/json
Vary: Accept
{"name": "Example"}
The Vary: Accept header tells caches that responses differ based on the Accept header—caching infrastructure should store separate copies for different Accept values.
API Versioning with Content Types
Content types enable elegant API versioning:
# Client requests v2 API
Accept: application/vnd.example.v2+json
# Server responds with v2 format
Content-Type: application/vnd.example.v2+json
# Client that still needs v1
Accept: application/vnd.example.v1+json
This approach keeps version information in content type rather than URL paths, enabling cleaner API evolution.
When a server cannot provide any format listed in Accept, it should respond with 406 Not Acceptable, listing available alternatives. However, many servers instead return a default format (usually JSON or HTML), ignoring the Accept header. Robust clients should handle both behaviors.
12345678910111213141516171819202122232425262728
# Browser navigation - prefers HTMLGET /article/123 HTTP/1.1Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 # JavaScript fetch - prefers JSONGET /api/article/123 HTTP/1.1Accept: application/json, text/plain, */* # Image loading - modern format preferenceGET /images/hero.img HTTP/1.1Accept: image/avif,image/webp,image/png,image/jpeg,*/* # Response with multiple representations availableHTTP/1.1 200 OKContent-Type: application/jsonVary: AcceptLink: </api/article/123>; rel="canonical"Link: </api/article/123>; rel="alternate"; type="application/xml"Link: </article/123>; rel="alternate"; type="text/html" # API versioning via Accept headerGET /users/123 HTTP/1.1Accept: application/vnd.myapp.v2+json HTTP/1.1 200 OKContent-Type: application/vnd.myapp.v2+json {"user_id": 123, "display_name": "Tanaka Yuki", "created_at": "2024-01-15T10:00:00Z"}Content types form the classification backbone of MIME and modern Internet protocols. Let's consolidate what we've learned:
What's Next
We've explored individual content types and how they classify content. The next page dives into multipart messages—how to construct and parse composite messages containing multiple parts, the boundary protocol, and nested structures that enable rich email content like HTML with inline images and multiple attachments.
You now understand MIME content types—the universal classification system enabling software worldwide to correctly interpret content. From simple text/plain to complex vendor-prefixed types with parameters, from discrete content to multipart composition, content types are the vocabulary of Internet data exchange. Next, we'll explore multipart message construction in depth.