Skip to content

CRUD resources

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

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 heterogeneous 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 HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

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

If a relationship is provided in the relationships member of the resource object, its value MUST be a relationship object with a data 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 identifiers.

For example:

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

{
  "data": {
    "type": "photos",
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "attributes": {
      "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

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

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

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 and a Location header is provided, 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",
    "attributes": {
      "title": "Ember Hamster",
      "src": "http://example.com/images/productivity.png"
    },
    "links": {
      "self": "http://example.com/photos/550e8400-e29b-41d4-a716-446655440000"
    }
  }
}
# 202 Accepted

If a request to create a resource has been accepted for processing, but the processing has not been completed by the time the server responds, the server MUST return a 202 Accepted status code.

# 204 No Content

If a POST request did include a Client-Generated ID and the requested resource has been created successfully, 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.

# 404 Not Found

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

# 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 object's type is not among the type(s) that constitute the collection represented by the endpoint.

A server SHOULD include error details and provide enough information to recognize the source of the conflict.

# Other Responses

A server MAY respond with other HTTP status codes.

A server MAY include error details with error responses.

A server MUST prepare responses, and a client MUST interpret responses, in accordance with HTTP semantics.

# Updating Resources

A resource 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 /orders/1 HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": {
    "type": "orders",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "attributes": {
      "billingName": "Michael Scarn"
    }
  }
}

# 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 attributes for a resource, the server MUST interpret the missing attributes as if they were included with their current values. The server MUST NOT interpret missing attributes as null values.

For example, the following PATCH request is interpreted as a request to update only the billingName and billingOrganisationName attributes of an order:

PATCH /orders/1 HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": {
    "type": "orders",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "attributes": {
      "billingName": "Mose Schrute",
      "billingOrganisationName": "Schrute Farms"
    }
  }
}

# Updating a Resource's Relationships

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

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

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

For instance, the following PATCH request will update the retailer relationship of an order:

PATCH /orders/1 HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": {
    "type": "orders",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "relationships": {
      "retailer": {
        "data": { "type": "retailers", "id": "1" }
      }
    }
  }
}

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

PATCH /orders/1 HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": {
    "type": "orders",
    "id": "1",
    "relationships": {
      "tags": {
        "data": [
          { "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

# 202 Accepted

If an update request has been accepted for processing, but the processing has not been completed by the time the server responds, the server MUST return a 202 Accepted status code.

# 200 OK

If a server accepts an update but also changes the resource(s) in ways other 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 MUST include a representation of the updated resource(s) as if a GET request was made to the request URL.

A server MUST return a 200 OK status code if an update is successful, the client's current fields remain up to date, and the server responds only with top-level meta data. In this case the server MUST NOT include a representation of the updated resource(s).

# 204 No Content

If an update is successful and the server doesn't update any fields besides those provided, the server MUST return either a 200 OK status code and response document (as described above) or a 204 No Content status code with no response document.

# 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 object's type and id do not match the server's endpoint.

A server SHOULD include error details and provide enough information to recognize the source of the conflict.

# Other Responses

A server MAY respond with other HTTP status codes.

A server MAY include error details with error responses.

A server MUST prepare responses, and a client MUST interpret responses, in accordance with HTTP semantics.

# Updating Relationships

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

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 order has many retailers, it is possible to remove one of the retailers from the order without deleting the person itself. Similarly, if an order 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 URL from a to-one relationship link as described below.

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

For example, the following request updates the retailer of an order:

PATCH /orders/1/relationships/retailer HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

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

And the following request clears the retailer of the same order:

PATCH /orders/1/relationships/retailer HTTP/1.1
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 successful response.

# Updating To-Many Relationships

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

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

If a client makes a PATCH request to a URL from a to-many relationship link, 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 order:

PATCH /orders/1/relationships/tags HTTP/1.1
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 order:

PATCH /orders/1/relationships/tags HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": []
}

If a client makes a POST request to a URL from a relationship link, the server MUST add the specified members to the relationship unless they are already present. 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 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 order with ID 1:

POST /orders/1/relationships/comments HTTP/1.1
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 URL from a relationship link 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 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 order with ID 1:

DELETE /orders/1/relationships/comments HTTP/1.1
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

# 202 Accepted

If a relationship update request has been accepted for processing, but the processing has not been completed by the time the server responds, the server MUST return a 202 Accepted status code.

# 204 No Content

A server MUST return a 204 No Content status code if an update is successful and the representation of the resource in the request matches the result.

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

# 200 OK

If a server accepts an update but also changes the targeted relationship(s) in other ways than those specified by the request, it MUST return a 200 OK response. The response document MUST include a representation of the updated relationship(s).

A server MUST return a 200 OK status code if an update is successful, the client's current data remain up to date, and the server responds only with top-level meta data. In this case the server MUST NOT include a representation of the updated relationship(s).

# 403 Forbidden

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

# Other Responses

A server MAY respond with other HTTP status codes.

A server MAY include error details with error responses.

A server MUST prepare responses, and a client MUST interpret responses, in accordance with HTTP semantics.

# Deleting Resources

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

DELETE /photos/1 HTTP/1.1
Accept: application/vnd.api+json

# Responses

# 202 Accepted

If a deletion request has been accepted for processing, but the processing has not been completed by the time the server responds, the server MUST return a 202 Accepted status code.

# 204 No Content

A server MUST return a 204 No Content status code if a deletion request is successful and no content is returned.

# 200 OK

A server MUST return a 200 OK status code if a deletion request is successful and the server responds with only top-level meta data.

# 404 NOT FOUND

A server SHOULD return a 404 Not Found status code if a deletion request fails due to the resource not existing.

# Other Responses

A server MAY respond with other HTTP status codes.

A server MAY include error details with error responses.

A server MUST prepare responses, and a client MUST interpret responses, in accordance with HTTP semantics.