Fork me on GitHub

Format

Status

This document is a work in progress and will change as implementation work progresses. See the Status page for more information.

Introduction

JSON API is a specification for how a client should request that resources be fetched or modified, and how a server should respond to those requests.

JSON API is designed to minimize both the number of requests and the amount of data transmitted between clients and servers. This efficiency is achieved without compromising readability, flexibility, or discoverability.

JSON API requires use of the JSON API media type (application/vnd.api+json) for exchanging data.

Conventions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119].

Extending

The base JSON API specification MAY be extended to support additional capabilities.

An extension MAY make changes to and deviate from the requirements of the base specification apart from this section, which remains binding.

Servers that support one or more extensions to JSON API MUST return those extensions in every response in the supported-ext media type parameter of the Content-Type header. The value of the supported-ext parameter MUST be a comma-separated (U+002C COMMA, ",") list of extension names.

For example: a response that includes the header Content-Type: application/vnd.api+json; supported-ext=bulk,jsonpatch indicates that the server supports both the "bulk" and "jsonpatch" extensions.

If an extension is used to form a particular request or response document, then it MUST be specified by including its name in the ext media type parameter with the Content-Type header. The value of the ext media type parameter MUST be formatted as a comma-separated (U+002C COMMA, ",") list of extension names and MUST be limited to a subset of the extensions supported by the server, which are listed in supported-ext of every response.

For example: a response that includes the header Content-Type: application/vnd.api+json; ext=ext1,ext2; supported-ext=ext1,ext2,ext3 indicates that the response document is formatted according to the extensions "ext1" and "ext2". Another example: a request that includes the header Content-Type: application/vnd.api+json; ext=ext1,ext2 indicates that the request document is formatted according to the extensions "ext1" and "ext2".

Clients MAY request a particular media type extension by including its name in the ext media type parameter with the Accept header. Servers that do not support a requested extension or combination of extensions MUST return a 406 Not Acceptable status code.

If the media type in the Accept header is supported by a server but the media type in the Content-Type header is unsupported, the server MUST return a 415 Unsupported Media Type status code.

Servers MUST NOT provide extended functionality that is incompatible with the base specification to clients that do not request the extension in the ext parameter of the Content-Type or the Accept header.

Note: Since extensions can contradict one another or have interactions that can be resolved in many equally plausible ways, it is the responsibility of the server to decide which extensions are compatible, and it is the responsibility of the designer of each implementation of this specification to describe extension interoperability rules which are applicable to that implementation.

Document Structure

This section describes the structure of a JSON API document, which is identified by the media type application/vnd.api+json. JSON API documents are defined in JavaScript Object Notation (JSON) [RFC4627].

Although the same media type is used for both request and response documents, certain aspects are only applicable to one or the other. These differences are called out below.

Unless otherwise noted, objects defined by this specification MUST NOT contain any additional members. Client and server implementations MUST ignore object members not recognized by this specification.

Note: These conditions for object members allow this specification to evolve through additive changes.

Top Level

A JSON object MUST be at the root of every JSON API response containing data. This object defines a document's "top level".

The document's "primary data" is a representation of the resource, collection of resources, or resource relationship primarily targeted by a request.

A document MUST contain either primary data or an array of error objects.

Primary data MUST appear under a top-level key named "data". Primary data MUST be either a single resource object, an array of resource objects, or a value representing a resource relationship.

{
  "data": {
    "type": "articles",
    "id": "1",
    // ... attributes of this article
  }
}

A logical collection of resources (e.g., the target of a to-many relationship) MUST be represented as an array, even if it only contains one item. A logically singular resource (e.g., the target of a to-one relationship) MUST be represented as a single resource object.

Error objects MUST appear under a top-level key named "errors".

A document's top level MAY also have the following members:

If any of these members appears in the top-level of a response, their values MUST comply with this specification.

Resource Objects

"Resource objects" appear in a JSON API document to represent resources.

A resource object MUST contain at least the following top-level members:

Exception: The id member is not required when the resource object originates at the client and represents a new resource to be created on the server.

In addition, a resource object MAY contain any of these top-level members:

Here's how an article (i.e. a resource of type "articles") might appear in a document:

// ...
{
  "type": "articles",
  "id": "1",
  "title": "Rails is Omakase",
  "links": {
    "author": {
      "self": "/articles/1/links/author",
      "related": "/articles/1/author",
      "linkage": { "type": "people", "id": "9" }
    }
  }
}
// ...

Attributes

A resource object MAY contain additional top-level members. These members represent "attributes" and may contain any valid JSON value.

Although has-one foreign keys (e.g. author_id) are often stored internally alongside other information to be represented in a resource object, these keys SHOULD NOT appear as attributes. If relations are provided, they MUST be represented under the "links object".

Complex Attributes

"Complex attributes" are attributes whose value is an object or array with any level of nesting. An object that constitutes or is contained in a complex attribute MUST reserve the id, type, links, and meta members for future use.

Fields

A resource object's attributes and relationships are collectively called its "fields".

Resource Identification

Every JSON API resource object is uniquely identified by a combination of its type and id members. This identification is used for linkage in compound documents and batch operations that modify multiple resources at a time.

A resource object's type and id pair MUST refer to a single, unique resource.

Resource Types

Each resource object MUST contain a type member, whose value MUST be a string. The type is used to describe resource objects that share common attributes and relationships.

Note: This spec is agnostic about inflection rules, so the value of type can be either plural or singular. However, the same value should be used consistently throughout an implementation.

Resource IDs

Each resource object MUST contain an id member, whose value MUST be a string.

Links

The value of the "links" key is a JSON object (a "links object") that represents related resources, keyed by the name of each association.

The key "self" is reserved within the links object for the resource URL, as described below.

Resource URLs

A resource object MAY include a URL in its links object, keyed by "self", that identifies the resource represented by the resource object.

// ...
{
  "type": "articles",
  "id": "1",
  "title": "Rails is Omakase",
  "links": {
    "self": "http://example.com/articles/1"
  }
}
// ...

A server MUST respond to a GET request to the specified URL with a response that includes the resource as the primary data.

Resource Relationships

A resource object MAY contain references to other resource objects ("relationships"). Relationships may be to-one or to-many. Relationships can be specified by including a member in a resource's links object.

The name of the relationship declared in the key SHALL NOT be "self".

The value of a relationship MUST be one of the following:

If a relationship is provided as a link object, it MUST contain at least one of the following:

A link object that represents a to-many relationship MAY also contain pagination links, as described below.

If a link object refers to resource objects included in the same compound document, it MUST include resource linkage to those resource objects.

Resource linkage MUST be represented as one of the following:

A "linkage object" is an object that identifies an individual related resource. It MUST contain type and id members.

Note: Resource linkage in a compound document allows a client to link together all of the included resource objects without having to GET any relationship URLs.

Note: If present, a related resource URL must be a valid URL, even if the relationship isn't currently associated with any target resources.

For example, the following article is associated with an author and comments:

// ...
{
  "type": "articles",
  "id": "1",
  "title": "Rails is Omakase",
  "links": {
    "self": "http://example.com/articles/1",
    "author": {
      "self": "http://example.com/articles/1/links/author",
      "related": "http://example.com/articles/1/author",
      "linkage": { "type": "people", "id": "9" }
    },
    "comments": "http://example.com/articles/1/comments"
  }
}
// ...

The author relationship includes a URL for the relationship itself (which allows the client to change the related author directly), a related resource URL to fetch the resource objects, and linkage information.

The comments relationship is simpler: it just provides a related resource URL to fetch the comments. The URL can therefore be specified directly as the attribute value.

Compound Documents

To reduce the number of HTTP requests, servers MAY allow responses that include related resources along with the requested primary resources. Such responses are called "compound documents".

In a compound document, all included resources MUST be represented as an array of resource objects in a top-level "included" member.

A complete example document with multiple included relationships:

{
  "data": [{
    "type": "articles",
    "id": "1",
    "title": "JSON API paints my bikeshed!",
    "links": {
      "self": "http://example.com/articles/1",
      "author": {
        "self": "http://example.com/articles/1/links/author",
        "related": "http://example.com/articles/1/author",
        "linkage": { "type": "people", "id": "9" }
      },
      "comments": {
        "self": "http://example.com/articles/1/links/comments",
        "related": "http://example.com/articles/1/comments",
        "linkage": [
          { "type": "comments", "id": "5" },
          { "type": "comments", "id": "12" }
        ]
      }
    }
  }],
  "included": [{
    "type": "people",
    "id": "9",
    "first-name": "Dan",
    "last-name": "Gebhardt",
    "twitter": "dgeb",
    "links": {
      "self": "http://example.com/people/9"
    }
  }, {
    "type": "comments",
    "id": "5",
    "body": "First!",
    "links": {
      "self": "http://example.com/comments/5"
    }
  }, {
    "type": "comments",
    "id": "12",
    "body": "I like XML better",
    "links": {
      "self": "http://example.com/comments/12"
    }
  }]
}

A compound document MUST NOT include more than one resource object for each type and id pair.

Note: In a single document, you can think of the type and id as a composite key that uniquely references resource objects in another part of the document.

Note: This approach ensures that a single canonical resource object is returned with each response, even when the same resource is referenced multiple times.

Meta information

As discussed above, the document MAY be extended to include meta-information as "meta" members in several locations: at the top-level, within resource objects, and within link objects.

All "meta" members MUST have an object as a value, the contents of which can be used for custom extensions.

For example:

{
  "meta": {
    "copyright": "Copyright 2015 Example Corp.",
    "authors": [
      "Yehuda Katz",
      "Steve Klabnik",
      "Dan Gebhardt"
    ]
  },
  "data": {
    // ...
  }
}

Any members MAY be specified within meta objects.

Top-level Links

The top-level links object MAY contain the following members:

Fetching Data

Data, including resources and relationships, can be fetched by sending a GET request to an endpoint.

JSON API requests MUST include an Accept header specifying the JSON API media type. This header value MUST also include media type extensions relevant to the request. Servers MUST return a 406 Not Acceptable status code if this header is missing or specifies an unsupported media type.

Note: Servers may support multiple media types at any endpoint. For example, a server may choose to support text/html in order to simplify viewing content via a web browser.

Responses can be further refined with the optional features described below.

Fetching Resources

A server MUST support fetching resource data for every URL provided as:

For example, the following request fetches a collection of articles:

GET /articles

The following request fetches an article:

GET /articles/1

And the following request fetches an article's author:

GET /articles/1/author

Responses

200 OK

A server MUST respond to a successful request to fetch an individual resource or resource collection with a 200 OK response.

A server MUST respond to a successful request to fetch a resource collection with an array of resource objects or an empty array ([]) as the response document's primary data.

For example, a GET request to a collection of articles could return:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "http://example.com/articles"
  },
  "data": [{
    "type": "articles",
    "id": "1",
    "title": "JSON API paints my bikeshed!"
  }, {
    "type": "articles",
    "id": "2",
    "title": "Rails is Omakase"
  }]
}

A similar response representing an empty collection would be:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "http://example.com/articles"
  },
  "data": []
}

A server MUST respond to a successful request to fetch an individual resource with a resource object or null provided as the response document's primary data.

Note: null is only an appropriate response for fetching a to-one related resource URL to indicate the absence of a resource in the relationship.

For example, a GET request to an individual article could return:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "http://example.com/articles/1"
  },
  "data": {
    "type": "articles",
    "id": "1",
    "title": "JSON API paints my bikeshed!",
    "links": {
      "author": {
        "related": "http://example.com/articles/1/author"
      }
    }
  }
}

If the above article's author is missing, then a GET request to that related resource would return:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "http://example.com/articles/1/author"
  },
  "data": null
}
404 Not Found

A server MUST return 404 Not Found when processing a request to fetch a resource that does not exist.

Note: When requesting a related resource that is not present, a server MUST respond with 200 OK and null or an empty array ([]) as the response document's primary data, as described above.

Other Responses

Servers MAY use other HTTP error codes to represent errors. Clients MUST interpret those errors in accordance with HTTP semantics. Error details MAY also be returned, as discussed below.

Fetching Relationships

A server MUST support fetching relationship data for every relationship URL provided as a self link as part of a link object.

For example, the following request fetches data about an article's comments:

GET /articles/1/links/comments

And the following request fetches data about an article's author:

GET /articles/1/links/author

Responses

200 OK

A server MUST respond to a successful request to fetch a relationship with a 200 OK response.

The primary data in the response document MUST match the appropriate value for resource linkage, as described above for link objects.

The top-level links object MAY contain self and related links, as described above for link objects.

For example, a GET request to a to-one relationship URL could return:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "/articles/1/links/author",
    "related": "/articles/1/author"
  },
  "data": {
    "type": "people",
    "id": "12"
  }
}

If the above relationship is empty, then a GET request to the same URL would return:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "/articles/1/links/author",
    "related": "/articles/1/author"
  },
  "data": null
}

A GET request to a to-many relationship URL could return:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "/articles/1/links/tags",
    "related": "/articles/1/tags"
  },
  "data": [
    { "type": "tags", "id": "2" },
    { "type": "tags", "id": "3" }
  ]
}

If the above relationship is empty, then a GET request to the same URL would return:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "/articles/1/links/tags",
    "related": "/articles/1/tags"
  },
  "data": []
}
404 Not Found

A server MUST return 404 Not Found when processing a request to fetch a relationship URL that does not exist.

Note: If a relationship URL exists but the relationship is empty, then 200 OK MUST be returned, as described above.

Other Responses

Servers MAY use other HTTP error codes to represent errors. Clients MUST interpret those errors in accordance with HTTP semantics. Error details MAY also be returned, as discussed below.

Inclusion of Related Resources

An endpoint MAY return resources related to the primary data by default.

An endpoint MAY also support custom inclusion of related resources based upon an include request parameter. This parameter MUST specify the relationship using the name used in the links section of the primary data.

If a client supplies an include parameter, the server MUST NOT include other resource objects in the included section of the compound document.

The value of the include parameter MUST be a comma-separated (U+002C COMMA, ",") list of relationship paths. A relationship path is a dot-separated (U+002E FULL-STOP, ".") list of relationship names. Each relationship name MUST be identical to the key in the links section of its parent resource object.

Note: For example, a relationship path could be comments.author, where comments is a relationship listed under a articles resource object, and author is a relationship listed under a comments resource object.

For instance, comments could be requested with an article:

GET /articles/1?include=comments

In order to request resources related to other resources, a dot-separated path for each relationship name can be specified:

GET /articles/1?include=comments.author

Note: A request for comments.author should not automatically also include comments in the response. This can happen if the client already has the comments locally, and now wants to fetch the associated authors without fetching the comments again.

Multiple related resources can be requested in a comma-separated list:

GET /articles/1?include=author,comments,comments.author

Sparse Fieldsets

A client MAY request that an endpoint return only specific fields in the response on a per-type basis by including a fields[TYPE] parameter.

Note: Only fields are affected; type, id, and (optionally) self are included as normal.

The value of the fields parameter MUST be a comma-separated (U+002C COMMA, ",") list that refers to the name(s) of the fields to be returned.

If a client requests a restricted set of fields, an endpoint MUST NOT include additional fields in the response.

GET /articles?include=author&fields[articles]=title,body&fields[people]=name

Sorting

A server MAY choose to support requests to sort resource collections according to one or more criteria ("sort fields").

Note: Although recommended, sort fields do not necessarily need to correspond to resource attribute and association names.

Note: It is recommended that dot-separated (U+002E FULL-STOP, ".") sort fields be used to request sorting based upon relationship attributes. For example, a sort field of +author.name could be used to request that the primary data be sorted based upon the name attribute of the author relationship.

An endpoint MAY support requests to sort the primary data with a sort query parameter. The value for sort MUST represent sort fields.

GET /people?sort=+age

An endpoint MAY support multiple sort fields by allowing comma-separated (U+002C COMMA, ",") sort fields. Sort fields SHOULD be applied in the order specified.

GET /people?sort=+age,+name

The sort order for each sort field MUST be specified with one of the following prefixes:

Note: By requiring a sort order prefix instead of allowing a default order, JSON API avoids setting requirements for the first character in sort field names.

GET /articles?sort=-created,+title

The above example should return the newest articles first. Any articles created on the same date will then be sorted by their title in ascending alphabetical order.

Pagination

A server MAY choose to limit the number of resources returned in a response to a subset ("page") of the whole set available.

A server MAY provide links to traverse a paginated data set ("pagination links").

Pagination links MUST appear in the link object that corresponds to a collection. To paginate the primary data, supply pagination links in the top-level links object. To paginate an included collection returned in a compound document, supply pagination links in the corresponding link object.

The following keys MUST be used for pagination links:

Keys MUST either be omitted or have a null value to indicate that a particular link is unavailable.

Concepts of order, as expressed in the naming of pagination links, MUST remain consistent with JSON API's sorting rules.

The page query parameter is reserved for pagination. Servers and clients SHOULD use this key for pagination operations.

Note: JSON API is agnostic about the pagination strategy used by a server. Effective pagination strategies include (but are not limited to): page-based, offset-based, and cursor-based. The page query parameter can be used as a basis for any of these strategies. For example, a page-based strategy might use query parameters such as page[number] and page[size], an offset-based strategy might use page[offset] and page[limit], while a cursor-based strategy might use page[cursor].

Filtering

The filter query parameter is reserved for filtering data. Servers and clients SHOULD use this key for filtering operations.

Note: JSON API is agnostic about the strategies supported by a server. The filter query parameter can be used as the basis for any number of filtering strategies.

Creating, Updating and Deleting Resources

A server MAY allow resources of a given type to be created. It MAY also allow existing resources to be modified or deleted.

Any requests that contain content MUST include a Content-Type header whose value is application/vnd.api+json. This header value MUST also include media type extensions relevant to the request.

A request MUST completely succeed or fail (in a single "transaction"). No partial updates are allowed.

Note: The type member is required in every resource object throughout requests and responses in JSON API. There are some cases, such as when POSTing to an endpoint representing heterogenous data, when the type could not be inferred from the endpoint. However, picking and choosing when it is required would be confusing; it would be hard to remember when it was required and when it was not. Therefore, to improve consistency and minimize confusion, type is always required.

Creating Resources

A resource can be created by sending a POST request to a URL that represents a collection of resources. The request MUST include a single resource object as primary data. The resource object MUST contain at least a type member.

For instance, a new photo might be created with the following request:

POST /photos
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": {
    "type": "photos",
    "title": "Ember Hamster",
    "src": "http://example.com/images/productivity.png",
    "links": {
      "photographer": {
        "linkage": { "type": "people", "id": "9" }
      }
    }
  }
}

If a relationship is provided in the links section of the resource object, its value MUST be a link object with a linkage member. The value of this key represents the linkage the new resource is to have.

Client-Generated IDs

A server MAY accept a client-generated ID along with a request to create a resource. An ID MUST be specified with an "id" key, the value of which MUST be a universally unique identifier. The client SHOULD use a properly generated and formatted UUID as described in RFC 4122 [RFC4122].

NOTE: In some use-cases, such as importing data from another source, it may be possible to use something other than a UUID that is still guaranteed to be globally unique. Do not use anything other than a UUID unless you are 100% confident that the strategy you are using indeed generates globally unique indentifiers.

For example:

POST /photos
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": {
    "type": "photos",
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "title": "Ember Hamster",
    "src": "http://example.com/images/productivity.png"
  }
}

A server MUST return 403 Forbidden in response to an unsupported request to create a resource with a client-generated ID.

Responses

201 Created

A server MUST respond to a successful resource creation request according to HTTP semantics.

The response MUST include a Location header identifying the location of the newly created resource.

If a POST request did not include a Client-Generated ID, and a resource has been created, the server MUST return a 201 Created status code.

The response MUST also include a document that contains the primary resource created.

If the resource object returned by the response contains a self key in its links member, the value of the self member MUST match the value of the Location header.

HTTP/1.1 201 Created
Location: http://example.com/photos/550e8400-e29b-41d4-a716-446655440000
Content-Type: application/vnd.api+json

{
  "data": {
    "type": "photos",
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "title": "Ember Hamster",
    "src": "http://example.com/images/productivity.png",
    "links": {
      "self": "http://example.com/photos/550e8400-e29b-41d4-a716-446655440000"
    }
  }
}
204 No Content

If a POST request did include a Client-Generated ID, the server MUST return either a 201 Created status code and response document (as described above) or a 204 No Content status code with no response document.

Note: If a 204 response is received the client should consider the resource object sent in the request to be accepted by the server, as if the server had returned it back in a 201 response.

403 Forbidden

A server MAY return 403 Forbidden in response to an unsupported request to create a resource.

409 Conflict

A server MUST return 409 Conflict when processing a POST request to create a resource with a client-generated ID that already exists.

A server MUST return 409 Conflict when processing a POST request in which the resource's type does not match the server's endpoint.

Other Responses

Servers MAY use other HTTP error codes to represent errors. Clients MUST interpret those errors in accordance with HTTP semantics. Error details MAY also be returned, as discussed below.

Updating Resources

A resource's attributes and relationships can be updated by sending a PATCH request to the URL that represents the resource.

The URL for a resource can be obtained in the self link of the resource object. Alternatively, when a GET request returns a single resource object as primary data, the same request URL can be used for updates.

The PATCH request MUST include a single resource object as primary data. The resource object MUST contain type and id members.

For example:

PATCH /articles/1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": {
    "type": "articles",
    "id": "1",
    "title": "To TDD or Not"
  }
}

Updating a Resource's Attributes

Any or all of a resource's attributes MAY be included in the resource object included in a PATCH request.

If a request does not include all of the fields for a resource, the server MUST interpret the missing fields as if they were included together with their current values. It MUST NOT interpret them as null values.

For example, the following PATCH request is interpreted as a request to update only the title and text attributes of an article:

PATCH /articles/1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": {
    "type": "articles",
    "id": "1",
    "title": "To TDD or Not",
    "text": "TLDR; It's complicated... but check your test coverage regardless."
  }
}

Updating a Resource's Relationships

If a relationship is provided in the links section of a resource object in a PATCH request, its value MUST be a link object with a linkage member. The relationship's value will be replaced with the value specified in this member.

For instance, the following PATCH request will update the title attribute and author relationship of an article:

PATCH /articles/1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": {
    "type": "articles",
    "id": "1",
    "title": "Rails is a Melting Pot",
    "links": {
      "author": {
        "linkage": { "type": "people", "id": "1" }
      }
    }
  }
}

Likewise, the following PATCH request performs a complete replacement of the tags for an article:

PATCH /articles/1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": {
    "type": "articles",
    "id": "1",
    "title": "Rails is a Melting Pot",
    "links": {
      "tags": {
        "linkage": [
          { "type": "tags", "id": "2" },
          { "type": "tags", "id": "3" }
        ]
      }
    }
  }
}

A server MAY reject an attempt to do a full replacement of a to-many relationship. In such a case, the server MUST reject the entire update, and return a 403 Forbidden response.

Note: Since full replacement may be a very dangerous operation, a server may choose to disallow it. For example, a server may reject full replacement if it has not provided the client with the full list of associated objects, and does not want to allow deletion of records the client has not seen.

Responses

204 No Content

A server MUST return a 204 No Content status code if an update is successful and the client's current attributes remain up to date.

200 OK

If a server accepts an update but also changes the resource(s) in other ways than those specified by the request (for example, updating the updated-at attribute or a computed sha), it MUST return a 200 OK response.

The response document for a 200 OK MUST include a representation of the updated resource(s) as if a GET request was made to the request URL.

403 Forbidden

A server MUST return 403 Forbidden in response to an unsupported request to update a resource or relationship.

404 Not Found

A server MUST return 404 Not Found when processing a request to modify a resource that does not exist.

A server MUST return 404 Not Found when processing a request that references a related resource that does not exist.

409 Conflict

A server MAY return 409 Conflict when processing a PATCH request to update a resource if that update would violate other server-enforced constraints (such as a uniqueness constraint on a property other than id).

A server MUST return 409 Conflict when processing a PATCH request in which the resource's type and id do not match the server's endpoint.

Other Responses

Servers MAY use other HTTP error codes to represent errors. Clients MUST interpret those errors in accordance with HTTP semantics. Error details MAY also be returned, as discussed below.

Updating Relationships

Although relationships can be modified along with resources (as described above), JSON API also supports updating of relationships independently at relationship URLs.

If a link object contains a relationship URL, then the server MUST respond to requests to that URL to update the relationship.

Note: Relationships are updated without exposing the underlying server semantics, such as foreign keys. Furthermore, relationships can be updated without necessarily affecting the related resources. For example, if an article has many authors, it is possible to remove one of the authors from the article without deleting the person itself. Similarly, if an article has many tags, it is possible to add or remove tags. Under the hood on the server, the first of these examples might be implemented with a foreign key, while the second could be implemented with a join table, but the JSON API protocol would be the same in both cases.

Note: A server may choose to delete the underlying resource if a relationship is deleted (as a garbage collection measure).

Updating To-One Relationships

A server MUST respond to PATCH requests to a to-one relationship URL as described below.

The PATCH request MUST include a top-level member named data containing one of:

For example, the following request updates the author of an article:

PATCH /articles/1/links/author
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": { "type": "people", "id": "12" }
}

And the following request clears the author of the same article:

PATCH /articles/1/links/author
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": null
}

If the relationship is updated successfully then the server MUST return a 204 No Content response.

Updating To-Many Relationships

A server MUST respond to PATCH, POST, and DELETE requests to a to-many relationship URL as described below.

For all request types, the body MUST contain a data member whose value is an empty array or an array of linkage objects.

If a client makes a PATCH request to a to-many relationship URL, the server MUST either completely replace every member of the relationship, return an appropriate error response if some resources can not be found or accessed, or return a 403 Forbidden response if complete replacement is not allowed by the server.

For example, the following request replaces every tag for an article:

PATCH /articles/1/links/tags
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": [
    { "type": "tags", "id": "2" },
    { "type": "tags", "id": "3" }
  ]
}

And the following request clears every tag for an article:

PATCH /articles/1/links/tags
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": []
}

If a client makes a POST request to a relationship URL, the server MUST append the specified members to the relationship using set semantics. This means that if a given type and id is already in the relationship, the server MUST NOT add it again.

Note: This matches the semantics of databases that use foreign keys for has-many relationships. Document-based storage should check the has-many relationship before appending to avoid duplicates.

If all of the specified resources can be added to, or are already present in, the relationship then the server MUST return a successful 204 No Content response.

Note: This approach ensures that a request is successful if the server's state matches the requested state, and helps avoid pointless race conditions caused by multiple clients making the same changes to a relationship.

In the following example, the comment with ID 123 is added to the list of comments for the article with ID 1:

POST /articles/1/links/comments
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": [
    { "type": "comments", "id": "123" }
  ]
}

If the client makes a DELETE request to a relationship URL, the server MUST delete the specified members from the relationship or return a 403 Forbidden response. If all of the specified resources are able to be removed from, or are already missing from, the relationship then the server MUST return a successful 204 No Content response.

Note: As described above for POST requests, this approach helps avoid pointless race conditions between multiple clients making the same changes.

Relationship members are specified in the same way as in the POST request.

In the following example, comments with IDs of 12 and 13 are removed from the list of comments for the article with ID 1:

DELETE /articles/1/links/comments
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": [
    { "type": "comments", "id": "12" },
    { "type": "comments", "id": "13" }
  ]
}

Note: RFC 7231 specifies that a DELETE request may include a body, but that a server may reject the request. This spec defines the semantics of a server, and we are defining its semantics for JSON API.

Responses

204 No Content

A server MUST return a 204 No Content status code if an update is successful and the client's current attributes remain up to date.

Note: This is the appropriate response to a POST request sent to a to-many relationship URL when that relationship already exists. It is also the appropriate response to a DELETE request sent to a to-many relationship URL when that relationship does not exist.

403 Forbidden

A server MUST return 403 Forbidden in response to an unsupported request to update a relationship.

Other Responses

Servers MAY use other HTTP error codes to represent errors. Clients MUST interpret those errors in accordance with HTTP semantics. Error details MAY also be returned, as discussed below.

Deleting Resources

An individual resource can be deleted by making a DELETE request to the resource's URL:

DELETE /photos/1

Responses

204 No Content

A server MUST return a 204 No Content status code if a delete request is successful.

Other Responses

Servers MAY use other HTTP error codes to represent errors. Clients MUST interpret those errors in accordance with HTTP semantics. Error details MAY also be returned, as discussed below.

Errors

Error objects provide additional information about problems encountered while performing an operation. Error objects MUST be returned as an array keyed by "errors" in the top level of a JSON API document, and SHOULD NOT be returned with any primary data.

An error object MAY have the following members:

Additional members MAY be specified within error objects.