Home / Blog / JSON tools

API & webhooks

JSON API Headers: Generic JSON and the JSON:API Media Type

Choose headers for ordinary JSON endpoints or the JSON:API specification, then check request serialization, response negotiation, and media-type errors.

Establish which meaning of JSON API applies

An API that sends JSON is not necessarily an implementation of the JSON:API specification. Many endpoints accept ordinary application/json and define their own document shape. JSON:API has a distinct media type and rules for resource documents. Check the service's contract before copying headers from a similarly named example.

Consider two fictional note services. One accepts a plain object containing title. Another accepts a resource document whose data member identifies a type and attributes. Sending either document to the other service can fail even though both documents are valid JSON. A header cannot convert one document model into the other.

Build a small JSON:API creation request

function noteCreationRequest(title) {
  if (typeof title !== "string" || !title.trim()) {
    throw new Error("A nonempty title is required.");
  }
  return {
    method: "POST",
    headers: {
      Accept: "application/vnd.api+json",
      "Content-Type": "application/vnd.api+json"
    },
    body: JSON.stringify({
      data: {type: "notes", attributes: {title}}
    })
  };
}

This example assumes that a particular service documents a notes resource and permits creation with a title attribute. It omits an id for the new resource. It does not promise that an arbitrary JSON:API endpoint exposes this resource or permits this operation.

For the title River & rail, parsing the generated body recovers the same string under data.attributes.title. A second title containing a quotation mark or Unicode character should round-trip just as accurately. JSON.stringify handles JSON escaping; HTML escaping is a separate concern when displaying a response.

Distinguish submitted content from acceptable responses

Content-Type identifies the representation being sent. Accept describes acceptable response formats. The JSON:API 1.1 negotiation rules require its media type for its payloads and allow ext and profile parameters. Do not append a charset parameter automatically to a JSON:API Content-Type.

An unsupported parameter on that request Content-Type requires a 415 response under the specification. Unacceptable JSON:API alternatives in Accept can instead lead to 406. Extensions and profiles have distinct negotiation rules; only add their identifiers when the service and client implement the intended semantics.

Adapt ordinary JSON examples deliberately

For a generic endpoint, its documentation may instead call for application/json and a body such as {"title":"Map notes"}. Change both the body shape and headers to match that documented contract. Renaming the media type while retaining an incompatible envelope creates a misleading reproduction.

The browser does not serialize a JavaScript object simply because a JSON Content-Type is present. Pass a serialized body when using fetch. Conversely, do not stringify a string that is already serialized unless the endpoint intentionally accepts a JSON string as its complete input.

The Fetch guide covers request construction and response handling. Inspect the returned HTTP status before applying the endpoint's success-document parser. A readable error response is different from a rejected network request, and each needs useful diagnostics.

Keep authentication and cross-origin policy separate

The media type does not supply authorization. Add the authentication mechanism documented by the service, and use synthetic credentials in examples. Do not put private keys into a browser request merely to make an experimental call succeed.

A browser's cross-origin policy can also prevent the request or hide response fields. Changing the media type to an unrelated value solely to avoid preflight is not a valid contract fix. The service must permit the intended origin, method and request headers when browser access is supported.

Verify exact headers and exact document shape

Test the builder with two distinct titles, then parse the body and assert the method, media type, resource type and title. Empty, whitespace-only and non-string titles should fail before any request is made. These tests verify this builder's small contract, not the full JSON:API specification.

Use the REST API Testing Tool to inspect an authorized endpoint's actual response. Record whether a failure is 415, 406, authentication-related or a body-validation error. Keep the server's redacted explanation with the reproduction so that a generic JSON problem is not confused with JSON:API negotiation.