Accept Header

Introduction

When a client sends an HTTP request to a server, it may be capable of handling several response formats. A browser may prefer HTML. A mobile application may prefer JSON. A legacy enterprise system may prefer XML. A report download client may expect PDF. The client communicates this preference using the Accept request header.

The Accept header is central to content negotiation. It tells the server which media type or response format the client is willing to receive. The server then tries to choose one of the requested formats and returns the selected format using the response Content-Type header. If none of the requested formats are supported, the server may return 406 Not Acceptable or follow another documented fallback behavior.

For API testers, the Accept header is important because it proves that an API returns responses in the expected format. A request can reach the correct endpoint and return a successful status code, but still be wrong if the client asked for JSON and the server returned plain text or HTML. Accept header testing is also useful for validating unsupported formats, wildcard behavior, multiple format preferences, q-values, file downloads, browser flows, and APIs that support both JSON and XML.

What Is the Accept Header?

The Accept header is an HTTP request header that specifies the media type or media types the client is willing to accept in the response. It is sent by the client to the server. It does not describe the request body. It describes the preferred response body.

A simple definition is this: the Accept header tells the server which response format the client prefers to receive. The basic format is:

Accept: media-type

For example:

Accept: application/json

This tells the server that the client wants a JSON response if possible. If the server supports JSON for that endpoint, it should return a response with Content-Type: application/json. If the server does not support JSON but supports another requested type, it may choose that. If it cannot produce any acceptable representation, it may return 406 Not Acceptable.

Why the Accept Header Is Needed

Different clients may need different response formats. A web browser commonly expects HTML for pages. A JavaScript frontend or mobile app commonly expects JSON for API responses. A legacy enterprise integration may still require XML. A reporting tool may request CSV or PDF. A media client may request an image or binary file. The Accept header allows the client to say what it can process.

Without the Accept header, the server must choose a default response format. Many modern REST APIs default to JSON, but this is not universal. Some systems return HTML by default when called from a browser, JSON when called from an API client, or XML for legacy routes. Explicit Accept headers reduce ambiguity and make tests more predictable.

The Accept header is especially useful when the same resource can be represented in multiple ways. A customer record may be available as JSON for an API client, XML for a partner integration, HTML for an admin page, or CSV for export. The resource is conceptually the same, but the representation differs. Accept helps the server choose the representation that best fits the client.

Where the Accept Header Is Used

The Accept header is used in HTTP requests. It is sent by the client to indicate the preferred response format. It is not normally sent by the server as a response header. The server's chosen response format is communicated using Content-Type.

A simple request may look like this:

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

The server understands that the client expects JSON. A matching response may be:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 101,
  "name": "John"
}

In this flow, Accept and Content-Type work together. Accept is the client's preference. Content-Type is the server's actual response format. If these do not align, the client may fail to parse the response or may behave differently from expected.

Common Accept Header Values

Common Accept values include application/json, application/xml, text/html, text/plain, image/png, image/jpeg, application/pdf, text/csv, and the wildcard value */*. Each value tells the server which response media type the client can handle.

application/json is the most common Accept value in REST APIs. application/xml is common in legacy systems and enterprise integrations. text/html is common for browser page requests. text/plain may be used for simple health checks or status endpoints. application/pdf is common for reports, invoices, statements, and downloadable documents. Image media types are used when requesting image resources.

The wildcard */* means the client can accept any response format. Many tools send this by default. While convenient, it is not always ideal for precise API testing because it allows the server to choose a default format. If the test specifically expects JSON, the test should send Accept: application/json and validate the response Content-Type.

application/json

application/json is the most common Accept value used by modern REST APIs. It tells the server that the client wants a JSON response. JSON is widely used because it is lightweight, readable, supported by JavaScript, easy to parse in most programming languages, and convenient for API automation.

A request may look like this:

GET /employees
Accept: application/json

The server may respond:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 101,
  "name": "John"
}

Testing JSON Accept behavior includes verifying that the server returns JSON Content-Type, valid JSON syntax, expected schema, expected fields, and consistent JSON error responses. A common defect is that normal responses return JSON while error responses return HTML from a gateway or framework. If the client requested JSON and the API contract promises JSON, error responses should be checked too.

application/xml

application/xml tells the server that the client prefers XML. XML is less common than JSON in modern public REST APIs, but it remains important in banking, insurance, healthcare, government, legacy enterprise systems, SOAP-style integrations, and document-centric workflows.

A request may look like this:

GET /employees
Accept: application/xml

The server may respond:

HTTP/1.1 200 OK
Content-Type: application/xml

<Employee>
  <Id>101</Id>
  <Name>John</Name>
</Employee>

If the API supports XML, tests should validate XML structure, schema where applicable, encoding, field mapping, and error format. If the API does not support XML, tests should verify the documented behavior, often 406 Not Acceptable or a default JSON response.

text/html and text/plain

text/html is used primarily by browsers. When a browser requests a page, it commonly sends an Accept header that includes HTML. The server returns an HTML document, and the browser renders it. APIs that serve both web pages and JSON data may use Accept to decide whether to return an HTML page or a JSON response.

text/plain is used when the client wants plain text. A simple health endpoint may return:

GET /status
Accept: text/plain

with a response such as:

Server Running

For API testing, text responses should be validated only when the endpoint contract supports them. If a JSON API unexpectedly returns text or HTML, it can break API clients. This is especially common when infrastructure returns a default HTML error page after gateway failures.

Accept Anything with Wildcards

The wildcard Accept value */* means the client can accept any media type. Many browsers and API tools include wildcard values to remain flexible. Example:

Accept: */*

This tells the server that the client has no strict format requirement. The server can choose the most appropriate default representation. For general browsing or exploratory testing, this may be acceptable. For precise API automation, it can be too loose.

If a test uses */* and the server returns JSON, the test may pass. But the same API might later return XML, HTML, or another default format and still technically satisfy the wildcard. If the business expectation is JSON, the test should request JSON explicitly. Wildcards are useful to test default behavior, but they should not replace format-specific validation.

Multiple Accept Values

The client can specify multiple acceptable formats in one Accept header. For example:

Accept: application/json, application/xml

This means JSON is acceptable and XML is also acceptable. The server chooses one of the formats it supports. If it supports both, it may choose the first one, choose based on server preference, or use quality values if present. The exact selection behavior should be documented when multiple formats are important.

Multiple Accept values are useful when clients can process more than one representation. A partner integration might prefer JSON but accept XML as a fallback. A browser might list HTML, images, and wildcard values depending on the resource being requested. Content negotiation allows the server and client to agree on a representation without changing the URL.

API testers should validate how the server behaves with multiple values. Does it choose the highest priority supported format? Does it ignore order? Does it return 406 when none are supported? Does response Content-Type clearly match the selected representation? These are contract questions, not assumptions.

Quality Values and q-values

Quality values, commonly called q-values, allow the client to rank acceptable formats. A q-value ranges from 0 to 1, where 1 is the highest preference. For example:

Accept: application/json;q=1.0, application/xml;q=0.8, text/plain;q=0.3

This means JSON is preferred, XML is acceptable if JSON is not available, and plain text is a lower preference. If the server supports JSON, it should return JSON. If it does not support JSON but supports XML, it may return XML. If none of the listed formats are supported, it may return 406 Not Acceptable.

q-values are more common in browser requests than in simple API testing, but they are worth understanding. Some clients send complex Accept headers automatically. A browser may send several media types with different priorities. An API gateway or backend framework may use these values to choose a response type.

Testing q-values is useful for APIs that explicitly support content negotiation. Create requests with different q-value priorities and verify the selected response Content-Type. Also test malformed q-values and unsupported values if the API contract defines behavior for them.

Content Negotiation

Content negotiation is the process of selecting the response representation based on request headers, especially Accept. The client sends its preferences. The server compares those preferences with the formats it can produce. The server then returns the chosen representation and identifies it with Content-Type.

A simple flow looks like this: the client sends Accept: application/json, the server chooses JSON, and the response returns Content-Type: application/json. If the client sends Accept: application/xml and the server supports XML, the response returns XML. If the client sends only unsupported formats, the server may return 406.

Content negotiation can apply to data format, language, encoding, and other representation choices. The Accept header handles media type negotiation. Related headers such as Accept-Language and Accept-Encoding handle language and compression preferences. Together, these headers allow clients and servers to communicate more flexibly.

Accept vs Content-Type

Accept and Content-Type are commonly confused, but the difference is straightforward. Accept specifies the desired response format. Content-Type specifies the actual format of the body being sent in the current message. Accept is sent by the client in the request. Content-Type can appear in both requests and responses.

Consider this request:

POST /users
Content-Type: application/json
Accept: application/json

This means the request body is JSON and the client wants a JSON response. Now consider this request:

POST /users
Content-Type: application/json
Accept: application/xml

This means the client sends JSON data but requests an XML response. If the server supports XML responses, it may return Content-Type: application/xml. If it does not, it may return 406 or a documented fallback.

In testing, do not use Accept when you mean Content-Type. If the server is failing to parse the request body, Content-Type is usually the first header to inspect. If the server returns the wrong response format, Accept and response Content-Type are the first headers to inspect.

What Happens If the Server Cannot Produce the Requested Format?

If the client requests a format the server cannot produce, the server may return 406 Not Acceptable. For example:

GET /users/101
Accept: application/xml

If the server supports only JSON, it may respond:

HTTP/1.1 406 Not Acceptable

This tells the client that the requested response format is not available. Some APIs choose a different behavior and return the default format, often JSON, even when the Accept header asks for something else. That can be practical, but it should be documented. Otherwise consumers and testers will not know whether unsupported Accept headers should fail or fall back.

When testing this behavior, use unsupported media types such as application/xml against JSON-only APIs, or unrealistic media types such as application/unknown. Validate the status code, response body, error schema, and response Content-Type. If the error itself is JSON, the response should usually declare JSON as its Content-Type.

Real-World Examples

In a REST API, a mobile app may send GET /users with Accept: application/json. The server returns user data with Content-Type: application/json. The app parses the JSON and displays the user list. If the server returns HTML instead, the app may fail because it expects JSON.

In a browser request, the client may send an Accept header that prefers HTML. The server returns Content-Type: text/html, and the browser renders the page. This is why the same server can support browser pages and API endpoints differently.

In a report download flow, the client may request Accept: application/pdf for an annual report. The server returns Content-Type: application/pdf, and the browser or client downloads or displays the PDF. If the report is not ready, the server may return a JSON error response with an appropriate error Content-Type.

In a legacy integration, a partner may request XML because its system cannot consume JSON. If the API supports XML, it should return XML. If the API no longer supports XML, it should return the documented failure response and provide migration guidance if required.

Accept Header in API Testing

API testers should validate supported formats. If the API supports JSON, send Accept: application/json and verify that the response Content-Type is JSON and the body is valid JSON. If XML is supported, send Accept: application/xml and validate XML structure. If plain text or PDF is supported, validate the appropriate content type and body behavior.

Unsupported formats should also be tested. If XML is not supported, send Accept: application/xml and verify whether the API returns 406 Not Acceptable or follows the documented fallback behavior. Do not assume one behavior without checking the specification.

Test multiple formats and wildcards where relevant. A request such as Accept: application/json, application/xml should produce a supported format. A request with Accept: */* should return the default supported format. If q-values are part of the contract, tests should verify that the server chooses the highest-priority supported format.

Response validation is critical. The server's Content-Type should match the selected response format. A JSON body with text/plain is a mismatch. An HTML error page returned to a JSON API client may indicate proxy or framework fallback behavior that needs correction.

Accept Header and Error Responses

Error responses should be tested with Accept headers too. If a client requests JSON and sends invalid input, the API may return 400 Bad Request, but the body should still follow the expected JSON error schema if that is the contract. A common defect is that success responses respect Accept, while error responses ignore it.

For example, a client sends:

POST /users
Content-Type: application/json
Accept: application/json

If the request body is invalid, the response should not suddenly become an HTML error page unless the API is documented that way. A consistent JSON error response helps clients handle failures safely.

Authentication and authorization errors should also be checked. A 401 or 403 response should return a content type the client can process. If the frontend or mobile app expects JSON, an HTML login page returned from a gateway can break the application. This often happens when API authentication and browser authentication are mixed incorrectly.

Accept Header and File Downloads

File downloads often depend on Accept behavior. A report endpoint may support PDF, CSV, or Excel output. The client can request one format with Accept or with a query parameter depending on the API design. If Accept is used, the response Content-Type should match the requested file type.

For example:

GET /reports/annual
Accept: application/pdf

The response should return Content-Type: application/pdf if the PDF is available. If the same endpoint supports CSV, a request with Accept: text/csv may return a CSV file. Tests should validate file type, Content-Type, Content-Disposition, file size, and whether the downloaded file opens correctly.

If the requested file format is unsupported, the API should return a clear error or documented fallback. Returning a JSON error body while declaring application/pdf is a common bug in file-download APIs. The body and Content-Type must stay consistent.

Accept Header and Versioned Media Types

Some APIs use versioned media types in the Accept header. Instead of placing the API version only in the URL, the client may request a versioned representation such as application/vnd.company.user.v2+json. This tells the server that the client wants version 2 of the user representation in JSON-compatible form.

This style is more common in mature public APIs and enterprise APIs that need long-term compatibility. It can keep URLs stable while allowing representations to evolve. However, it also makes Accept header testing more important because the requested version is part of the header contract.

Testing versioned Accept values should include supported versions, unsupported versions, deprecated versions, default version behavior, and response Content-Type. If a client requests version 2, the response should not silently return version 1 fields unless the contract allows fallback. Clear errors are better than hidden version mismatches.

Best Practices

Specify the expected response format using the Accept header when the response format matters. For most REST API tests, use Accept: application/json if JSON is expected. Avoid relying on broad wildcards for precise contract tests.

Ensure the server returns a matching Content-Type. If the client requests JSON and the server chooses JSON, the response should say Content-Type: application/json or a compatible JSON media type. If the server cannot produce the requested format, return 406 Not Acceptable or follow the documented API behavior.

Use standard MIME types. Avoid unclear values such as json or text/json unless the API contract explicitly supports them. Standard media types improve interoperability across tools, SDKs, browsers, and automation frameworks.

Support content negotiation only where it adds value. If the API supports only JSON, document that clearly. If it supports multiple formats, define selection rules, default behavior, unsupported format behavior, and how q-values are handled. Ambiguous content negotiation creates inconsistent clients and fragile tests.

Common Mistakes

A common mistake is confusing Accept with Content-Type. Accept is the format the client wants to receive. Content-Type is the format of the body being sent in the current message. A request can use both, but they do different jobs.

Another mistake is omitting Accept and assuming JSON. Many APIs default to JSON, but not all do. Even when the server defaults to JSON, tests that explicitly request JSON are clearer and more stable.

A third mistake is returning the wrong response Content-Type. If the client requests JSON and the body is JSON, the response should not say text/plain. Incorrect Content-Type can cause parsing and interoperability issues.

Another mistake is ignoring unsupported Accept values. If the API contract says unsupported formats return 406, tests should confirm that. If the API contract says unsupported formats fall back to JSON, tests should confirm that too. Silent inconsistency is the real problem.

Teams also sometimes forget to test error responses with Accept. A successful response may return JSON correctly, while errors return HTML. This breaks clients and should be caught early.

Accept Header Defaults in Tools and Frameworks

One practical challenge with Accept header testing is that tools and frameworks often add default values. A browser may send a long Accept header with several media types. An API testing tool may send */* unless the tester sets a specific value. A generated SDK may always send application/json. A gateway or backend framework may choose JSON by default even when the client did not explicitly ask for it.

These defaults can hide problems. A test may pass in Postman because Postman sends broad headers, while a production client fails because it sends a stricter Accept value. Another test may pass because the framework always returns JSON, but the API documentation says unsupported formats should return 406. If testers do not inspect the actual raw request, they may not realize which Accept value was sent.

For automation, it is better to be explicit. If the test expects JSON, set Accept: application/json. If the test is checking default behavior, omit Accept deliberately and name the test accordingly. If the test is checking wildcard behavior, send Accept: */* intentionally. If the test is checking unsupported format behavior, send a clearly unsupported media type and assert the documented response.

This discipline makes tests easier to understand. Future maintainers can read the test and know whether the format was chosen intentionally. It also prevents accidental dependency on tool defaults, which can change when a tool, library, or framework is upgraded.

Designing Automated Tests for Accept Header Behavior

Automated Accept header tests should focus on the API contract rather than every possible media type. Start with the formats the endpoint officially supports. For a JSON-only endpoint, the most important test is that Accept: application/json returns JSON with the expected response body. Then test what happens when the Accept header is missing, wildcard, or unsupported.

For an endpoint that supports multiple formats, create focused tests for each supported format. A user endpoint that supports JSON and XML should have one test for JSON response structure and another for XML response structure. If q-values are supported, add a test that sends multiple values with priorities and verifies the selected Content-Type.

Keep assertions meaningful. Do not only check that the response status is 200. Also check the response Content-Type and parse the body using the expected parser. If the server returns Content-Type: application/json but the body is invalid JSON, the test should fail. If the server returns valid JSON but labels it as text/plain, the test should also fail when the contract requires JSON Content-Type.

Use negative tests carefully. Unsupported Accept tests should not be written as random noise. They should prove a documented behavior such as 406 Not Acceptable, default JSON fallback, or a standard error schema. This makes the test valuable instead of brittle.

Troubleshooting Accept Header Issues

When an API returns an unexpected format, first inspect the raw request. Was the Accept header sent? Was it sent with the expected value? Did the API testing tool add a wildcard automatically? Did a browser send a complex Accept header that caused the server to choose HTML instead of JSON?

Next, inspect the response Content-Type and body. Does the declared Content-Type match the actual body? If the response is an error, did it come from the application, gateway, proxy, or web server? Infrastructure layers may return their own HTML errors even when the backend API normally returns JSON.

Then compare behavior against the API specification. If the API supports only JSON, unsupported Accept values should behave as documented. If the API supports multiple formats, verify selection rules. If q-values are involved, confirm that the server chose the highest-priority supported type.

A precise defect report should include the request method, URL, Accept header value, response status code, response Content-Type, response body sample, expected format, and actual format. This helps developers decide whether the issue is content negotiation, route configuration, serialization, gateway behavior, or documentation mismatch.

Interview-Ready Explanation

The Accept header is an HTTP request header that specifies the media type or response format the client prefers to receive from the server. It is used in content negotiation. The client can request formats such as application/json, application/xml, text/html, text/plain, or application/pdf. The server selects a supported format and indicates its choice using the response Content-Type header.

If the server cannot produce any of the requested formats, it may return 406 Not Acceptable or follow the documented API fallback behavior. The Accept header is different from Content-Type. Accept tells the server what the client wants to receive. Content-Type tells the receiver what format is actually being sent in the current message.

In API testing, validating the Accept header ensures that the API returns responses in the expected format, handles supported and unsupported media types correctly, respects content negotiation rules, and returns a matching Content-Type header.

Key Takeaway

The Accept header is the client's way of saying, "This is the response format I can handle." It helps the server choose the right representation for the response. It is most commonly used to request JSON in REST APIs, but it can also request XML, HTML, plain text, images, PDFs, CSV files, or custom versioned media types.

For API testers, the practical rule is simple: when response format matters, send the correct Accept header and verify the returned Content-Type and body. Test supported formats, unsupported formats, wildcards, multiple values, q-values, error responses, and file downloads where relevant. Strong Accept header testing makes API behavior more predictable and prevents format-related integration defects.