Skip to article
TOOLS. SYSTEMS. BETTER DECISIONS.
Stack & Method

The journal

Accept vs Content-Type: what they do and how they differ

A clear, practical explanation of the HTTP Accept and Content-Type headers, how they interact, and how this differs from ETag behavior, with examples and a checklist.

Client and server exchanging documents

Accept tells the server what media types the client is willing to receive; Content-Type labels the actual media type of the message body being sent or returned. Accept guides the server’s choice, while Content-Type declares what was chosen. ETag, often seen alongside these, identifies a specific version of the resource and is about caching and concurrency, not format.

What Accept means

Accept is primarily a request header that lists the media types the client can process, sometimes with weighted preferences. The server performs content negotiation and then signals its choice with Content-Type in the response. Examples include Accept: application/json or lists with q-values like image/avif,image/webp,image/*;q=0.8,*/*;q=0.5. Tools like curl default to Accept: */* unless you set something else. In some contexts, Accept can also appear in responses to indicate what a resource can accept later, but its core use is request-side preference signaling (see MDN: Accept).

GET /users/123 HTTP/1.1
Host: api.example.com
Accept: application/json

Key points:

  • Expresses what the client can handle; it does not prove what the server will send.
  • The server’s final choice is communicated with Content-Type.
  • Q-values (e.g., ;q=0.8) indicate preference ordering, not guarantees.

Citation: MDN’s definition and examples of request negotiation and default patterns (MDN Accept).

What Content-Type means

Content-Type is a representation header that states the media type of the message body, with optional parameters like charset or boundary. In responses, it tells clients how to interpret the returned data. In requests that include a body (such as POST or PUT), it tells the server how to interpret what you’re sending. If a server strictly enforces media handling and the request body’s type isn’t supported, it may return 415 Unsupported Media Type (see MDN Content-Type).

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{"id":123,"name":"Ada"}

Common patterns and parameters:

  • application/json for API responses or request bodies.
  • text/html; charset=utf-8 for web pages.
  • multipart/form-data; boundary=... for form uploads (boundary is required for multipart).

Note: Some browsers perform MIME sniffing; to prevent that and enforce your declared type, set X-Content-Type-Options: nosniff (MDN Content-Type, and media type structure in MDN Media types).

Illustrative HTTP request and response panel

Where ETag fits (and why it’s different)

An ETag identifies a specific version of a resource. Clients use it for conditional requests: If-None-Match for cache validation and If-Match for optimistic concurrency control. If the validator matches and the resource hasn’t changed, the server can return 304 Not Modified with no body, allowing the client to use its cached representation. If a write is attempted with a stale validator, the server can return 412 Precondition Failed. ETag concerns versioning and caching, not the media format; Accept and Content-Type handle format (MDN ETag).

Putting them together: a practical flow

GET /profile HTTP/1.1
Host: example.com
Accept: application/json
If-None-Match: "abc123"

Server behavior:

  • If unchanged: 304 Not Modified (no body). The client keeps using its cached JSON and its existing Content-Type label (MDN ETag).
  • If changed: respond with 200 OK, a fresh body, a new ETag, and a definitive Content-Type labeling the new representation.
HTTP/1.1 200 OK
Content-Type: application/json
ETag: "def456"

{"name":"Riley","plan":"pro"}
Documents moving between client and server

Practical tips and common mistakes

  • Only set Content-Type when there is a message body to describe (e.g., JSON in POST or PUT). This header labels what you send; it does not request what you want back (MDN Content-Type).
  • Use Accept to state what you can parse. The server chooses one option and confirms it via Content-Type (MDN Accept).
  • For multipart form uploads, always include a valid boundary in Content-Type (MDN Content-Type).
  • Prevent MIME sniffing for stricter security by sending X-Content-Type-Options: nosniff with responses that must not be reinterpreted (MDN Content-Type).
  • Remember that ETag controls cache validation and concurrency. It is orthogonal to Accept/Content-Type, which control format (MDN ETag).

Put this into practice

Write down what the request body contains and what response formats the client accepts as separate fields. Inspect a real request and response pair before fixing a media-type error, instead of changing both headers blindly.

Quick checklist: using Accept, Content-Type and ETag correctly

Related reading on Stack & Method

FAQ

Do I need both headers in API calls?
They serve different roles. Use Accept to state what formats you can parse; use Content-Type when you send a body to label its format. The server confirms its decision with Content-Type (MDN Accept, MDN Content-Type).

Does Accept affect ETag matching?
Accept influences which representation the server selects; ETag identifies the version of that selected resource representation for caching or concurrency. They are complementary but solve different problems (MDN ETag).

Stack & Method logo

After checking HTTP media types, CheckMySchema shows how to assert a response body against a schema in REST Assured. Schema validation does not replace checking status and header behaviour. Validate JSON Schema in REST Assured.

Sources and further reading

Your privacy choices

Optional analytics helps us improve these guides. It stays off until you allow it. Privacy details