Content Negotiation

Use Accept and Content-Type correctly for robust clients.

On this page

Content negotiation in practice

Content negotiation is how clients and servers agree on formats. For most modern APIs, this means JSON in and JSON out, but you still should handle Accept and Content-Type correctly.

Accept

The client tells the server what response formats it can handle.

Accept: application/json

Content-Type

The client tells the server what it is sending.

Content-Type: application/json

Common production approach

  • Default to JSON responses.
  • Require Content-Type for requests with a body.
  • Return 415 Unsupported Media Type for unknown Content-Type.
  • Return 406 Not Acceptable only if you truly support multiple formats.

Example: strict JSON request handling

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

{ "name": "Ada" }

Example: unsupported media type (415)

HTTP/1.1 415 Unsupported Media Type
Content-Type: application/json

{
  "title": "Unsupported Media Type",
  "status": 415,
  "detail": "Use Content-Type: application/json"
}

Common mistakes

  • Accept ignored but Content-Type not validated (garbage payloads sneak in)
  • Returning text/html error pages from API endpoints
  • Inventing custom formats without strong reasons

Checklist

  • Requests with JSON body require Content-Type: application/json
  • Responses include Content-Type: application/json
  • Errors are returned as JSON consistently