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, and discoverability.

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

A JSON API server supports fetching of resources through the HTTP method GET. In order to support creating, updating and deleting resources, it must support use of the HTTP methods POST, PUT and DELETE, respectively.

A JSON API server may also optionally support modification of resources with the HTTP PATCH method [RFC5789] and the JSON Patch format [RFC6902]. JSON Patch support is possible because, conceptually, JSON API represents all of a domain's resources as a single JSON document that can act as the target for operations. Resources are grouped at the top level of this document according to their type. Each resource can be identified at a unique path within this document.

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].

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.

Top Level

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

A document's top level SHOULD contain a representation of the resource or collection of resources primarily targeted by a request (i.e. the "primary resource(s)").

The primary resource(s) SHOULD be keyed either by their resource type or the generic key "data".

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

No other members should be present at the top level of a document.

Resource Representations

This section describes how resources can be represented throughout a JSON API document. It applies to primary as well as linked resources.

Individual Resource Representations

An individual resource SHOULD be represented as a single "resource object" (described below) or a string value containing its ID (also described below).

The following post is represented as a resource object:

{
  "posts": {
    "id": "1",
    // ... attributes of this post
  }
}

This post is represented simply by its ID:

{
  "posts": "1"
}

Resource Collection Representations

A collection of any number of resources SHOULD be represented as an array of resource objects or IDs, or as a single "collection object" (described below).

The following posts are represented as an array of resource objects:

{
  "posts": [{
    "id": "1"
    // ... attributes of this post
  }, {
    "id": "2"
    // ... attributes of this post
  }]
}

These posts are represented as an array of IDs:

{
  "posts": ["1", "2"]
}

These comments are represented by a single "collection" object:

{
  "comments": {
    "href": "http://example.com/comments/5,12,17,20",
    "ids": [ "5", "12", "17", "20" ],
    "type": "comments"
  }
}

Resource Objects

Resource objects have the same internal structure, regardless of whether they represent primary or linked resources.

Here's how a post (i.e. a resource of type "posts") might appear in a document:

{
  "posts": {
    "id": "1",
    "title": "Rails is Omakase"
  }
}

In the example above, the post's resource object is simply:

//...
  {
    "id": "1",
    "title": "Rails is Omakase"
  }
//...

This section will focus exclusively on resource objects, outside of the context of a full JSON API document.

Resource Attributes

There are four reserved keys in resource objects:

Every other key in a resource object represents an "attribute". An attribute's value may be any JSON value.

Resource IDs

Each resource object SHOULD contain a unique identifier, or ID, when available. IDs MAY be assigned by the server or by the client, as described below, and SHOULD be unique for a resource when scoped by its type. An ID SHOULD be represented by an "id" key and its value MUST be a string which SHOULD only contain alphanumeric characters, dashes and underscores.

IDs can be used with URL templates to fetch related resources, as described below.

In scenarios where uniquely identifying information between client and server is unnecessary (e.g. read-only, transient entities), JSON API allows for omitting IDs.

Resource Types

The type of each resource object can usually be determined from the context in which it is contained. As discussed above, resource objects are typically keyed by their type in a document.

Each resource object MAY contain a "type" key to explicitly designate its type.

The "type" key is REQUIRED when the type of a resource is not otherwise specified in a document.

Resource URLs

The URL of each resource object MAY be specified with the "href" key. Resource URLs SHOULD only be specified by the server and therefore are typically only included in response documents.

//...
  [{
    "id": "1",
    "href": "http://example.com/comments/1",
    "body": "Mmmmmakase"
  }, {
    "id": "2",
    "href": "http://example.com/comments/2",
    "body": "I prefer unagi"
  }]
//...

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

It is generally more efficient to specify URL templates at the root level of a response document rather than to specify individual URLs per resource.

Resource Relationships

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

For example, the following post is associated with a single author and a collection of comments:

//...
  {
    "id": "1",
    "title": "Rails is Omakase",
    "links": {
      "author": "9",
      "comments": [ "5", "12", "17", "20" ]
    }
  }
//...
To-One Relationships

To-one relationships MUST be represented with one of the formats for individual resources described above.

For example, the following post is associated with a single author, identified by ID:

//...
  {
    "id": "1",
    "title": "Rails is Omakase",
    "links": {
      "author": "17"
    }
  }
//...

And here's an example of a linked author represented as a resource object:

//...
  {
    "id": "1",
    "title": "Rails is Omakase",
    "links": {
      "author": {
        "href": "http://example.com/people/17",
        "id": "17",
        "type": "people"
      }
    }
  }
//...

A blank has-one relationship SHOULD be represented with a null value. For example, the following post has no author:

//...
  {
    "id": "1",
    "title": "Rails is Omakase",
    "links": {
      "author": null
    }
  }
//...
To-Many Relationships

To-many relationships MUST be represented with one of the formats for resource collections described above.

For example, the following post is associated with several comments, identified by their IDs:

//...
  {
    "id": "1",
    "title": "Rails is Omakase",
    "links": {
      "comments": [ "5", "12", "17", "20" ]
    }
  }
//...

And here's an example of an array of comments linked as a collection object:

//...
  {
    "id": "1",
    "title": "Rails is Omakase",
    "links": {
      "comments": {
        "href": "http://example.com/comments/5,12,17,20",
        "ids": [ "5", "12", "17", "20" ],
        "type": "comments"
      }
    }
  }
//...

A blank has-many relationship SHOULD be represented with an empty array value. For example, the following post has no comments:

//...
  {
    "id": "1",
    "title": "Rails is Omakase",
    "links": {
      "comments": []
    }
  }
//...

Collection Objects

A "collection object" contains one or more of the members:

A server that provides a collection object that contains an "href" MUST respond to a GET request to the specified URL with a response that includes the referenced objects as a collection of resource objects.

URL Templates

A top-level "links" object MAY be used to specify URL templates that can be used to formulate URLs for resources according to their type.

For example:

{
  "links": {
    "posts.comments": "http://example.com/comments?posts={posts.id}"
  },
  "posts": [{
    "id": "1",
    "title": "Rails is Omakase"
  }, {
    "id": "2",
    "title": "The Parley Letter"
  }]
}

In this example, fetching http://example.com/comments?posts=1 will fetch the comments for "Rails is Omakase" and fetching http://example.com/comments?posts=2 will fetch the comments for "The Parley Letter".

Here's another example:

{
  "links": {
    "posts.comments": "http://example.com/comments/{posts.comments}"
  },
  "posts": [{
    "id": "1",
    "title": "Rails is Omakase",
    "links": {
      "comments": [ "1", "2", "3", "4" ]
    }
  }]
}

In this example, the posts.comments variable is expanded by "exploding" the array specified in the "links" section of each post. The URI template specification [RFC6570] specifies that the default explosion is to percent encode the array members (e.g. via encodeURIComponent() in JavaScript) and join them by a comma. In this example, fetching http://example.com/comments/1,2,3,4 will return a list of all comments.

The top-level "links" object has the following behavior:

Here is another example that uses a has-one relationship:

{
  "links": {
    "posts.author": "http://example.com/people/{posts.author}"
  },
  "posts": [{
    "id": "1",
    "title": "Rails is Omakase",
    "links": {
      "author": "12"
    }
  }, {
    "id": "2",
    "title": "The Parley Letter",
    "links": {
      "author": "12"
    }
  }, {
    "id": "3",
    "title": "Dependency Injection is Not a Virtue",
    "links": {
      "author": "12"
    }
  }]
}

In this example, the URL for the author of all three posts is http://example.com/people/12.

Top-level URL templates allow you to specify relationships as IDs, but without requiring that clients hard-code information about how to form the URLs.

NOTE: In case of conflict, an individual resource object's links object will take precedence over a top-level links object.

Compound Documents

To save HTTP requests, responses may optionally allow for the inclusion of linked resources along with the requested primary resources. Such response documents are called "compound documents".

In a compound document, linked resources MUST be included as resource objects in a top level "linked" object, in which they are grouped together in arrays according to their type.

The type of each relationship MAY be specified in a resource-level or top- level "links" object with the "type" key. This facilitates lookups of linked resource objects by the client.

{
  "links": {
    "posts.author": {
      "href": "http://example.com/people/{posts.author}",
      "type": "people"
    },
    "posts.comments": {
      "href": "http://example.com/comments/{posts.comments}",
      "type": "comments"
    }
  },
  "posts": [{
    "id": "1",
    "title": "Rails is Omakase",
    "links": {
      "author": "9",
      "comments": [ "1", "2", "3" ]
    }}, {
    "id": "2",
    "title": "The Parley Letter",
    "links": {
      "author": "9",
      "comments": [ "4", "5" ]
   }}, {
    "id": "1",
    "title": "Dependency Injection is Not a Virtue",
    "links": {
      "author": "9",
      "comments": [ "6" ]
    }
  }],
  "linked": {
    "people": [{
      "id": "9",
      "name": "@d2h"
    }],
    "comments": [{
      "id": "1",
      "body": "Mmmmmakase"
    }, {
      "id": "2",
      "body": "I prefer unagi"
    }, {
      "id": "3",
      "body": "What's Omakase?"
    }, {
      "id": "4",
      "body": "Parley is a discussion, especially one between enemies"
    }, {
      "id": "5",
      "body": "The parsley letter"
    }, {
      "id": "6",
      "body": "Dependency Injection is Not a Vice"
    }]
  }
}

This approach ensures that a single canonical representation of each document is returned with each response, even when the same document is referenced multiple times (in this example, the author of the three posts). Along these lines, if a primary document is linked to another primary or linked document, it should not be duplicated within the "linked" object.

URLs

Reference Document

When determining an API's URL structure, it is helpful to consider that all of its resources exist in a single "reference document" in which each resource is addressable at a unique path. Resources are grouped by type at the top level of this document. Individual resources are keyed by ID within these typed collections. Attributes and links within individual resources are uniquely addressable according to the resource object structure described above.

This concept of a reference document is used to determine appropriate URLs for resources as well as their relationships. It is important to understand that this reference document differs slightly in structure from documents used to transport resources due to different goals and constraints. For instance, collections in the reference document are represented as sets because members must be addressable by ID, while collections are represented as arrays in transport documents because order is significant.

URLs for Resource Collections

The URL for a collection of resources SHOULD be formed from the resource type.

For example, a collection of resources of type "photos" will have the URL:

/photos

URLs for Individual Resources

Collections of resources SHOULD be treated as sets keyed by resource ID. The URL for an individual resource SHOULD be formed by appending the resource's ID to the collection URL.

For example, a photo with an ID of "1" will have the URL:

/photos/1

The URL for multiple individual resources SHOULD be formed by appending a comma-separated list of resource IDs to the collection URL.

For example, the photos with IDs of "1", "2" and "3" will collectively have the URL:

/photos/1,2,3

Alternative URLs

Alternative URLs for resources MAY optionally be specified in responses with "href" members or URL templates.

Relationship URLs

A resource's relationship MAY be accessible at a URL formed by appending /links/<relationship-name> to the resource's URL. This relative path is consistent with the internal structure of a resource object.

For example, a photo's collection of linked comments will have the URL:

/photos/1/links/comments

A photo's reference to an individual linked photographer will have the URL:

/photos/1/links/photographer

A server MUST represent "to-one" relationships as individual resources and "to-many" relationships as resource collections.

Fetching Resources

A resource, or collection of resources, can be fetched by sending a GET request to the URL described above.

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

Filtering

A server MAY choose to support requests to filter resources according to specific criteria.

Filtering SHOULD be supported by appending parameters to the base URL for the collection of resources to be filtered.

For example, the following is a request for all comments associated with a particular post:

GET /comments?post=1

With this approach, multiple filters MAY be applied to a single request:

GET /comments?post=1&author=12

This specification only supports filtering based upon strict matching. Additional filtering allowed by an API should be specified in its profile (see Extending).

Inclusion of Linked Resources

A server MAY choose to support returning compound documents that include both primary and linked resource objects.

An endpoint MAY return resources linked to the primary resource(s) by default.

An endpoint MAY also support custom inclusion of linked resources based upon an include request parameter. This parameter should specify the path to one or more resources relative to the primary resource. If this parameter is used, ONLY the requested linked resources should be returned alongside the primary resource(s).

For instance, comments could be requested with a post:

GET /posts/1?include=comments

In order to request resources linked to other resources, the dot-separated path of each relationship should be specified:

GET /posts/1?include=comments.author

Note: a request for comments.author should not automatically also include comments in the response (although comments will obviously need to be queried in order to fulfill the request for their authors).

Multiple linked resources could be requested in a comma-separated list:

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

Sparse Fieldsets

A server MAY choose to support requests to return only specific fields in resource object.

An endpoint MAY support requests that specify fields for the primary resource type with a fields parameter.

GET /people?fields=id,name,age

An endpoint MAY support requests that specify fields for any resource type with a fields[TYPE] parameter.

GET /posts?include=author&fields[posts]=id,title&fields[people]=id,name

An endpoint SHOULD return a default set of fields in a resource object if no fields have been specified for its type, or if the endpoint does not support use of either fields or fields[TYPE].

An endpoint MAY also choose to always return a limited set of non-specified fields, such as id or href.

Note: fields and fields[TYPE] can not be mixed. If the latter format is used, then it must be used for the primary resource type as well.

Sorting

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

An endpoint MAY support requests to sort the primary resource type with a sort parameter.

GET /people?sort=age

An endpoint MAY support multiple sort criteria by allowing comma-separated fields as the value for sort. Sort criteria should be applied in the order specified.

GET /people?sort=age,name

The default sort order SHOULD be ascending. A - prefix on any sort field specifies a descending sort order.

GET /posts?sort=-created,title

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

An endpoint MAY support requests to sort any resource type with a sort[TYPE] parameter.

GET /posts?include=author&sort[posts]=-created,title&sort[people]=name

If no sort order is specified, or if the endpoint does not support use of either sort or sort[TYPE], then the endpoint SHOULD return resource objects sorted with a repeatable algorithm. In other words, resources SHOULD always be returned in the same order, even if the sort criteria aren't specified.

Note: sort and sort[TYPE] can not be mixed. If the latter format is used, then it MUST be used for the primary resource type as well.

Creating, Updating and Deleting Resources

A server MAY allow resources that can be fetched to also be created, modified and deleted.

A server MAY allow multiple resources to be updated in a single request, as discussed below. Updates to multiple resources MUST completely succeed or fail. No partial updates are allowed.

Any requests that contain content MUST include a Content-Type header whose value is application/vnd.api+json.

Creating Resources

A server that supports creating resources MUST support creating individual resources and MAY optionally support creating multiple resources in a single request.

One or more resources can be created by making a POST request to the URL that represents a collection of resources to which the new resource should belong.

Creating an Individual Resource

A request to create an individual resource MUST include a single primary resource object.

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

{
  "photos": {
    "title": "Ember Hamster",
    "src": "http://example.com/images/productivity.png"
  }
}

Creating Multiple Resources

A request to create multiple resources MUST include a collection of primary resource objects.

For instance, multiple photos might be created with the following request:

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

{
  "photos": [{
    "title": "Ember Hamster",
    "src": "http://example.com/images/productivity.png"
  }, {
    "title": "Mustaches on a Stick",
    "src": "http://example.com/images/mustaches.png"
  }]
}

Responses

201 Created

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

When one or more resources has been created, the server MUST return a 201 Created status code.

The response MUST include a Location header identifying the location of all resources created by the request.

If a single resource is created and that resource's object includes an href key, the Location URL MUST match the href value.

The response SHOULD also include a document that contains the primary resource(s) created. If absent, the client SHOULD treat the transmitted document as accepted without modification.

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

{
  "photos": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "href": "http://example.com/photos/550e8400-e29b-41d4-a716-446655440000",
    "title": "Ember Hamster",
    "src": "http://example.com/images/productivity.png"
  }
}
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.

Client-Generated IDs

A server MAY accept client-generated IDs along with requests to create one or more resources. IDs MUST be specified with an "id" key, the value of which MUST be a properly generated and formatted UUID.

For example:

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

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

Updating Resources

A server that supports updating resources MUST support updating individual resources and MAY optionally support updating multiple resources in a single request.

Resources can be updated by making a PUT request to the URL that represents either the individual or multiple individual resources.

Updating an Individual Resource

To update an individual resource, send a PUT request to the URL that represents the resource. The request MUST include a single top-level resource object.

For example:

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

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

Updating Multiple Resources

To update multiple resources, send a PUT request to the URL that represents the multiple individual resources (NOT the entire collection of resources). The request MUST include a top-level collection of resource objects that each contain an "id" member.

For example:

PUT /articles/1,2
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "articles": [{
    "id": "1",
    "title": "To TDD or Not"
  }, {
    "id": "2",
    "title": "LOL Engineering"
  }]
}

Updating Attributes

To update one or more attributes of a resource, the primary resource object should include only the attributes to be updated. Attributes omitted from the resource object should not be updated.

For example, the following PUT request will only update the title and text attributes of an article:

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

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

Updating Relationships

Updating To-One Relationships

To-one relationships MAY be updated along with other attributes by including them in a links object within the resource object in a PUT request.

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

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

{
  "articles": {
    "title": "Rails is a Melting Pot",
    "links": {
      "author": "1"
    }
  }
}

In order to remove a to-one relationship, specify null as the value of the relationship.

Alternatively, a to-one relationship MAY be accessible at its relationship URL (see above).

A PUT request sent to the URL of a relationship SHOULD update the relationship. For example:

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

{
  "people": "12"
}

A PUT request SHOULD succeed regardless of whether a relationship is currently defined.

A to-one relationship MAY alternatively be added by sending a POST request with an individual primary resource to the URL of the relationship. For example:

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

{
  "people": "12"
}

A POST request should only succeed if no relationship is currently defined.

A to-one relationship MAY be removed by sending a DELETE request to the URL of the relationship. For example:

DELETE /articles/1/links/author

A DELETE request should only succeed if the relationship is currently defined.

Updating To-Many Relationships

To-many relationships MAY optionally be updated with other attributes by including them in a links object within the document in a PUT request.

For instance, the following PUT request performs a complete replacement of the tags for an article:

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

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

In order to remove every member of a to-many relationship, specify an empty array ([]) as the value of the relationship.

Alternatively, a to-many relationship MAY optionally be accessible at its relationship URL (see above).

A PUT request sent to the URL of a relationship SHOULD completely replace every member of the relationship. For example:

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

{
  "tags": ["2", "3"]
}

Replacing a complete set of data is not always appropriate in a distributed system which may involve many editors. An alternative is to allow relationships to be added and removed individually. This can be done by making fine-grained requests to the relationship URL.

A to-many relationship MAY be added by sending a POST request with a single resource ID to the URL of the relationship. For example:

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

{
  "comments": "1"
}

More than one relationship MAY be added by sending an array of resource IDs. For example:

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

{
  "comments": ["1", "2"]
}

To-many relationships MAY be deleted individually by sending a DELETE request to the URL of the relationship:

DELETE /articles/1/links/tags/1

Multiple to-many relationships MAY be deleted by sending a DELETE request to the URL of the relationships:

DELETE /articles/1/links/tags/1,2

Responses

204 No Content

A server SHOULD return a 204 No Content status code if an update is successful and the client's current attributes remain up to date. This applies to PUT requests as well as POST and DELETE requests that modify links without affecting other attributes of a resource.

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 updatedAt attribute or a computed sha), it SHOULD 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.

404 Not Found

A server should return 404 Not Found when processing a request to modify or delete a resource or relationship that does not exist.

409 Conflict

A server should return 409 Conflict when processing a POST request to create a resource or relationship that already exists.

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

A server MAY optionally allow multiple resources to be deleted with a DELETE request to their URL:

DELETE /photos/1,2,3

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 are specialized resource objects that MAY be returned in a response to provide additional information about problems encountered while performing an operation. Error objects SHOULD be returned as a collection keyed by "errors" in the top level of a JSON API document, and SHOULD NOT be returned with any other top level resources.

An error object MAY have the following members:

Additional members MAY be specified within error objects.

Implementors MAY choose to use an alternative media type for errors.

PATCH Support

JSON API servers MAY opt to support HTTP PATCH requests that conform to the JSON Patch format [RFC6902]. There are JSON Patch equivalant operations for the operations described above that use POST, PUT and DELETE. From here on, JSON Patch operations sent in a PATCH request will be referred to simply as "PATCH operations".

PATCH requests MUST specify a Content-Type header of application/json-patch+json.

PATCH operations MUST be sent as an array to conform with the JSON Patch format. A server MAY limit the type, order and count of operations allowed in this top level array.

Request URLs

The URL for each PATCH request SHOULD map to the resource(s) or relationship(s) to be updated.

Every "path" within a PATCH operation SHOULD be relative to the request URL. The request URL and the PATCH operation's "path" are complementary and combine to target a particular resource, collection, attribute, or relationship.

PATCH operations MAY be allowed at the root URL of an API. In this case, every "path" within a PATCH operation MUST include the full resource URL. This allows for general "fire hose" updates to any resource represented by an API. As stated above, a server MAY limit the type, order and count of bulk operations.

Creating a Resource with PATCH

To create a resource, perform an "add" operation with a "path" that points to the end of its corresponding resource collection ("/-"). The "value" should contain a resource object.

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

PATCH /photos
Content-Type: application/json-patch+json
Accept: application/json

[
  {
    "op": "add",
    "path": "/-",
    "value": {
      "title": "Ember Hamster",
      "src": "http://example.com/images/productivity.png"
    }
  }
]

Updating Attributes with PATCH

To update an attribute, perform a "replace" operation with the attribute's name specified as the "path".

For instance, the following request should update just the src property of the photo at /photos/1:

PATCH /photos/1
Content-Type: application/json-patch+json

[
  { "op": "replace", "path": "/src", "value": "http://example.com/hamster.png" }
]

Updating Relationships with PATCH

To update a relationship, send an appropriate PATCH operation to the corresponding relationship's URL.

A server MAY also support updates at a higher level, such as the resource's URL (or even the API's root URL). As discussed above, the request URL and each operation's "path" must be complementary and combine to target a particular relationship's URL.

Updating To-One Relationships with PATCH

To update a to-one relationship, perform a "replace" operation with a URL and "path" that targets the relationship. The "value" should be an individual resource representation.

For instance, the following request should update the author of an article:

PATCH /article/1/links/author
Content-Type: application/json-patch+json

[
  { "op": "replace", "path": "/", "value": "1" }
]

To remove a to-one relationship, perform a remove operation on the relationship. For example:

PATCH /article/1/links/author
Content-Type: application/json-patch+json

[
  { "op": "remove", "path": "/" }
]

Updating To-Many Relationships with PATCH

While to-many relationships are represented as a JSON array in a GET response, they are updated as if they were a set.

To add an element to a to-many relationship, perform an "add" operation that targets the relationship's URL. Because the operation is targeting the end of a collection, the "path" must end with "/-". The "value" should be a representation of an individual resource or collection of resources.

For example, consider the following GET request:

GET /photos/1
Content-Type: application/vnd.api+json

{
  "links": {
    "comments": "http://example.com/comments/{comments}"
  },
  "photos": {
    "id": "1",
    "href": "http://example.com/photos/1",
    "title": "Hamster",
    "src": "images/hamster.png",
    "links": {
      "comments": [ "1", "5", "12", "17" ]
    }
  }
}

You could move comment 30 to this photo by issuing an add operation in the PATCH request:

PATCH /photos/1/links/comments
Content-Type: application/json-patch+json

[
  { "op": "add", "path": "/-", "value": "30" }
]

To remove a to-many relationship, perform a "remove" operation that targets the relationship's URL. Because the operation is targeting a member of a collection, the "path" MUST end with "/<id>".

For example, to remove comment 5 from this photo, issue this "remove" operation:

PATCH /photos/1/links/comments
Content-Type: application/json-patch+json

[
  { "op": "remove", "path": "/5" }
]

Deleting a Resource with PATCH

To delete a resource, perform an "remove" operation with a URL and "path" that targets the resource.

For instance, photo 1 might be deleted with the following request:

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

[
  { "op": "remove", "path": "/" }
]

Responses

204 No Content

A server MUST return a 204 No Content status code in response to a successful PATCH request in which 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 updatedAt attribute or a computed sha), it MUST return a 200 OK response as well as a representation of the updated resources.

The server MUST specify a Content-Type header of application/json. The body of the response MUST contain an array of JSON objects, each of which MUST conform to the JSON API media type (application/vnd.api+json). Response objects in this array MUST be in sequential order and correspond to the operations in the request document.

For instance, a request may create two photos in separate operations:

PATCH /photos
Content-Type: application/json-patch+json
Accept: application/json

[
  {
    "op": "add",
    "path": "/-",
    "value": {
      "title": "Ember Hamster",
      "src": "http://example.com/images/productivity.png"
    }
  },
  {
    "op": "add",
    "path": "/-",
    "value": {
      "title": "Mustaches on a Stick",
      "src": "http://example.com/images/mustaches.png"
    }
  }
]

The response would then include corresponding JSON API documents contained within an array:

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

[
  {
    "photos": [{
      "id": "123",
      "title": "Ember Hamster",
      "src": "http://example.com/images/productivity.png"
    }]
  }, {
    "photos": [{
      "id": "124",
      "title": "Mustaches on a Stick",
      "src": "http://example.com/images/mustaches.png"
    }]
  }
]

Other Responses

When a server encounters one or more problems while processing a PATCH request, it SHOULD specify the most appropriate HTTP error code in the response. Clients MUST interpret those errors in accordance with HTTP semantics.

A server MAY choose to stop processing PATCH operations as soon as the first problem is encountered, or it MAY continue processing operations and encounter multiple problems. For instance, a server might process multiple attribute updates and then return multiple validation problems in a single response.

When a server encounters multiple problems from a single request, the most generally applicable HTTP error code should be specified in the response. For instance, 400 Bad Request might be appropriate for multiple 4xx errors or 500 Internal Server Error might be appropriate for multiple 5xx errors.

A server MAY return error objects that correspond to each operation. The server MUST specify a Content-Type header of application/json and the body of the response MUST contain an array of JSON objects, each of which MUST conform to the JSON API media type (application/vnd.api+json). Response objects in this array MUST be in sequential order and correspond to the operations in the request document. Each response object SHOULD contain only error objects, since no operations can be completed successfully when any errors occur. Error codes for each specific operation SHOULD be returned in the "status" member of each error object.

HTTP Caching

Servers MAY use HTTP caching headers (ETag, Last-Modified) in accordance with the semantics described in HTTP 1.1.