What is the application/problem+json media type defined by RFC 9457, and which members does a problem document define?
answer
- problem+json = standard error envelope
- type, title, status, detail, instance — all optional
- type = URI, the machine key; about:blank default
- title = per class, detail = per occurrence
- 9457 obsoletes 7807; extensions are top-level
basics
~20 sIt is a standard JSON format for HTTP error bodies, media type application/problem+json. Its members are type (a URI identifying the problem kind), title, status, detail and instance — all optional, plus your own extension members.
solid answer
~50 sRFC 9457 (which obsoletes RFC 7807) standardises "Problem Details" so APIs stop inventing an error envelope each time. The body is JSON served as `application/problem+json` with five defined members: - **`type`** — a URI reference identifying the *kind* of problem. This is the stable, machine-readable discriminator. Defaults to `"about:blank"` when absent. - **`title`** — a short human-readable summary of the problem type; should not change from occurrence to occurrence. - **`status`** — the HTTP status code, duplicated in the body for convenience when the body is stored or forwarded. - **`detail`** — a human-readable explanation *specific to this occurrence*. - **`instance`** — a URI reference identifying this specific occurrence. All are optional, and you add **extension members** as extra top-level fields for API-specific data. The point is that generic tooling, generated clients and shared middleware can parse any compliant API's errors, and the distinct media type lets a client tell an error document apart from a normal JSON payload.
code
http · 10 linesHTTP/1.1 403 Forbidden
Content-Type: application/problem+json
{
"type": "https://api.example.com/problems/insufficient-funds",
"title": "Insufficient funds",
"status": 403,
"detail": "Your account balance is 30 credits but the transfer requires 50.",
"instance": "/accounts/12345/transfers/98765"
}go deeper
Name the media type and list the five members with a one-line meaning for each.
Explain type as the stable machine key, the about:blank default, and the title-versus-detail distinction.
Add extension members, the ignore-unknown-members rule, and the 7807-to-9457 lineage with framework support.
Weigh adoption as an interoperability decision: standard envelope and generated-client support versus the breaking-change cost on an established public API.
## The problem it solves Every HTTP API invents an error body. One returns `{"error": "..."}`, another `{"code", "message"}`, another a nested `{"errors": [...]}`. None of it is interoperable, so every client and every piece of shared tooling writes bespoke parsing. RFC 9457, *Problem Details for HTTP APIs* (which obsoletes RFC 7807 and is the current specification), defines one format so this stops being a per-API design exercise. ## The media type The body is JSON, but it is served with `Content-Type: application/problem+json` rather than `application/json`. The distinct type matters: a client can tell, from the header alone, that this payload is an error description rather than a normal representation, which is useful for generic middleware and for endpoints whose success payload is also JSON. (An XML variant, `application/problem+xml`, is also defined.) ## The five defined members **`type`** — a URI reference identifying the problem *kind*. This is the stable identifier clients branch on; it plays the role a symbolic error code plays in a hand-rolled envelope, but namespaced by URI so two APIs cannot collide. If omitted it is assumed to be `"about:blank"`, which means "the problem has no more specific semantics than the HTTP status code". **`title`** — a short, human-readable summary of the *type*. It should stay the same for every occurrence of that type, because it describes the class, not the instance. It exists so a human can read the document without dereferencing the type URI. **`status`** — the HTTP status code. It duplicates the status line, which is deliberate: problem documents get logged, forwarded and stored, and the copy keeps the document self-describing. The authoritative value is still the status line; a mismatch is a bug in the server. **`detail`** — human-readable explanation *specific to this occurrence* ("Your balance is 30, but the transfer requires 50"). It is prose for humans; clients should not parse it. **`instance`** — a URI reference identifying this particular occurrence, often a path that can be dereferenced for more information, or an opaque identifier of the failed operation. Every member is optional. A minimal valid document is `{}` — which is legal but useless; in practice you always send at least `type`, `title` and `status`. ## Extension members Anything else you need goes as an extra top-level member: a balance, a limit, a retry hint, a per-field breakdown. Consumers must ignore members they don't recognise, which is what makes adding them a non-breaking change. ## Contract rules for consumers Two rules make problem documents safe to evolve: 1. **Ignore unknown members.** Otherwise no server can ever add anything. 2. **Branch on `type`, not on `title` or `detail`.** The human-readable members are free to be reworded and localized. ## Where it shows up Because it is a standard, framework support exists out of the box — Spring Boot exposes it via its `ProblemDetail` type and can produce problem documents for framework-raised errors, and ASP.NET Core returns problem documents by default for error status codes and validation failures. That built-in support is often the practical reason a team adopts it: the standard envelope is what you get for free. ## When it is a poor fit If you have an existing public API with a widely-adopted error envelope, switching media type and shape is a breaking change with real cost; the interoperability win is smaller than it looks when your consumers are all first-party. The strongest cases for adopting it are new APIs, and APIs consumed by generated clients or third parties.
- What is the difference between the title and detail members?Title describes the problem type and should be identical for every occurrence of that type — "Insufficient funds". Detail describes this specific occurrence and may include concrete values — "Your balance is 30 but the transfer requires 50". Neither is meant for programmatic branching; that is the type member's job.
- Why duplicate the HTTP status inside the body when it is already in the status line?So the document stays self-describing when it is logged, forwarded through a gateway, or stored separately from the response. The status line remains authoritative — if the two disagree the server has a bug, and consumers should trust the status line. It is a convenience field, not a second source of truth.
saying these in an interview costs you the question
- Serving a problem document as application/json instead of application/problem+json
- Treating title or detail as the machine-readable identifier instead of type
- Believing all five members are required, when every member is optional
- Assuming the body status member overrides the HTTP status line
- Referring to it as RFC 7807 as the current spec — 9457 obsoletes it