MIME Types in REST API Design: Content-Type, Accept, and Vendor Types
Content-Type and Accept headers are your API's format contract. In HTTP, Content-Type describes the format of the body you are sending. Accept declares the format you expect in return. Together, they form the content negotiation mechanism that allows a single endpoint to serve multiple formats without separate URLs.1 For REST APIs that exclusively serve JSON, setting both headers explicitly in every request removes ambiguity about format expectations. Many APIs serve JSON by default regardless of Accept, but a well-designed API performs content negotiation and returns the format the client requested. Vendor-specific MIME types using the +json suffix pattern allow APIs to express their schema in the MIME type string itself, enabling clients and intermediaries to understand the structure without reading documentation.2 Building on this, versioning via MIME types using the vnd. prefix and a version parameter is an established alternative to URL-based API versioning.
Setting Content-Type on request bodies
When sending a request body, Content-Type declares the format of the data in that body. A POST request sending JSON must include Content-Type: application/json; otherwise the server may reject the body or misparse it.3 For form submissions, Content-Type: application/x-www-form-urlencoded or Content-Type: multipart/form-data are appropriate depending on whether binary data is included. An empty body (such as GET or DELETE requests without a body) should not include a Content-Type header at all, since the header implies a body is present.
Content-Type versus Accept for bodyless requests
Consequently, middleware that automatically appends Content-Type headers to all requests can cause issues with bodyless requests. Furthermore, the Content-Type header applies to the request body only; the Accept header governs the response format. Some developers confuse the two, setting Content-Type on a GET request and expecting it to control the response format, when Accept is the correct header for that purpose.
Content negotiation with Accept and q-values
The Accept header tells the server which response formats the client supports. A value of Accept: application/json requests a JSON response. Accept: */* accepts any format, which is the browser default. Multiple formats are expressed with comma separation and optional quality values: Accept: application/json, application/xml;q=0.9, */*;q=0.8. The q parameter ranges from 0 to 1; higher values are preferred. Servers that implement content negotiation read the Accept header and respond with the highest-preference format they support, setting the matching Content-Type on the response.
Strict versus lenient content negotiation
Strict content negotiation returns 406 Not Acceptable when no supported format matches the Accept header, which forces the client to handle the error and retry with a different format.3 Lenient negotiation ignores the Accept header entirely and returns a default format, typically JSON, which simplifies client code but breaks the content negotiation contract. Most public APIs use lenient negotiation for simplicity, but strict negotiation is more correct when clients explicitly declare supported formats and the server must respect that contract.
Custom vendor MIME types and the +json suffix pattern
RFC 6838 defines structured syntax suffixes for MIME types. The +json suffix indicates that a MIME type's underlying representation is JSON, regardless of the specific vendor type.4 application/vnd.api+json (JSON:API), application/problem+json (RFC 9457 HTTP problem details), and application/merge-patch+json (RFC 7396 JSON Merge Patch) are widely used examples. Vendor types with the vnd. prefix identify organisation or product-specific formats. Building on this, an API can version its format through the MIME type using the Accept and Content-Type headers: Accept: application/vnd.myapi.v2+json requests the v2 format without changing the URL. This approach avoids URL path versioning (/v1/, /v2/) at the cost of more complex header handling. Clients that do not support a specific version can fall back to application/json if the server allows it through its content negotiation logic.
Hypermedia API types and structured JSON media types
Beyond plain application/json, several structured media types layer specific schema conventions on top of JSON. Hypertext Application Language (HAL) defines a JSON structure where resources include _links and _embedded properties for hypermedia navigation; its registered media type is application/vnd.hal+json.5 JSON:API defines a strict response envelope with data, errors, and meta top-level properties; its registered type is application/vnd.api+json. Both formats allow API clients to discover related resources through typed links rather than relying on out-of-band documentation.
Choosing a hypermedia type commits your API to that format's conventions for pagination, relationship linking, and error encoding. application/problem+json (RFC 9457) is a narrower choice: it standardises only error responses, defining type, title, status, detail, and instance fields. Many APIs return application/json for success responses and application/problem+json for error responses, giving clients a predictable structure for error handling without requiring a full hypermedia framework for success payloads.
MIME type versioning as an alternative to URL versioning
The +json suffix pattern combined with the vnd. prefix allows API version information in the media type string itself.2 An API can negotiate Accept: application/vnd.myapi.v2+json to return a v2 response format at the same URL, avoiding URL path fragmentation such as /v1/ and /v2/. Version negotiation through media types requires clients to send the correct Accept header and handle 406 responses when requesting unsupported versions; it works best for APIs where different client versions must coexist for extended periods and where format changes are significant enough to warrant separate MIME type identifiers.
The trade-off is that clients must understand the versioning scheme embedded in the media type, whereas URL versioning is visible and easy to reason about from request logs alone. Teams choose media type versioning when they expect long-lived clients that cannot be forced to upgrade on a schedule. pick a registered +json vendor type rather than inventing a custom one.
When to use this
Use this guide when designing or auditing a REST API's content-type handling, implementing content negotiation, or choosing between URL versioning and MIME type versioning.
Examples
Fetch with explicit Content-Type and Accept headers
Always set both headers for API requests: Content-Type for the request body format and Accept for the expected response format.
Accept header with quality values for content negotiation
Express format preferences in order. The server responds with the highest-q format it supports.
Vendor MIME type with version in Accept header
Request a specific API version via MIME type instead of URL path versioning.
- 1.
Mozilla Developer Network, "Content negotiation," developer.mozilla.org, accessed June 2026. https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Content_negotiation
- 2.
Alexandre Allouin Pompey, "Media Type Specifications and Registration Procedures," RFC 6838, IETF, January 2013. https://www.rfc-editor.org/info/rfc6838/
- 3.
Roy T. Fielding and Julian Reschke, "HTTP Semantics," RFC 9110, IETF, January 2024. https://www.rfc-editor.org/info/rfc9110/
- 4.
"application/problem+json," IANA, iana.org, accessed June 2026. https://www.iana.org/assignments/media-types/application/problem+json
- 5.
"application/vnd.api+json," IANA, iana.org, accessed June 2026. https://www.iana.org/assignments/media-types/application/vnd.api+json